21 Aralık 2012 Cuma

HttpURLConnection İle Web Sayfası İçeriği Almak

Java'da basit bir şekilde ve herhangi bir ekstra kütüphane kullanmadan HTTPURLConnection sınıfı ile bir web sitesine bağlanıp içeriğini almak konusunda ufak bir kod parçası ile örnek vereceğim. Bu işlemi, bir web sayfasını tamamen String olarak çekip parse etmek ya da GET, POST vs. ile çalışan bir REST servisi çağırmak için kullanabilirsiniz.

Aşağıdaki örnekte http://www.mehmetaktas.org?param1=VALUE1&param2=VALUE2 şeklinde bir adresin içeriğini çekeceğiz.

public String getURLContent(){
        String uri = "http://www.mehmetaktas.org?param1=value1&param2=value2";
        HttpURLConnection connection = null;        
        
        try {
            
            //Bağlantımızı açıyoruz
            URL url = new URL(uri);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");//POST, PUT, DELETE ...
            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setDoOutput(true);
            /*
             * Content-Type, Content-Language gibi request property set etmek
             * istersek aşağıdaki metod kullanılabilir:
             * connection.setRequestProperty("Content-Language", "tr-TR");
             */
            //Response'ı alıyoruz
            InputStream is = connection.getInputStream();
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            String line;
            StringBuilder response = new StringBuilder();            
            while ((line = rd.readLine()) != null) {
                response.append(line);
                response.append('\r');
            }
            rd.close();
            is.close();
            
           return response.toString();
            
        } 
        catch (Exception e) {} 
        finally {
            if (connection != null) {
                connection.disconnect();                
            }
        }
    } 

httpurlconnection, screenscraper, java, url, connection, web page, parse, rest, get, post )

13 Aralık 2012 Perşembe

Operation Not Allowed After ResultSet Closed

Merhaba,

JDBC kullanarak Java'da veritabanı bağlantısı yapıp veri çekmeye çalışırken "rs.next()"ile bir veriye ulaşırız. Bu metodu çağırdığımız esnada "java.sql.SQLException: Operation not allowed after ResultSet closed" şeklinde bir taha alıyorsanız olası bir kaç sebebi var. Bu sebeplerin başında ResultSet nesnenizi kullanırken bir döngü ya da başka bir metodun içerisinde "rs.close()" metodunu kullanarak ya da nesneyi null yaparak hata alma durumunuz vardır. Bu problemi, biraz araştırarak çözebilirsiniz fakat "Ben ResultSet nesnemi kesinlikle kapatmıyorum ya da null yapmıyorum neden böyle oluyor?" derseniz sebebi bulmak biraz zor olabilir. Böyle bir durum başıma geldi ve çözümünden bahsedeceğim.

Java tarafında veritabanına bağlanırken ResultSet nesnesini doldurmak için bir Statement ya da PreparedStatement nesnesi kullanırız. Bu nesne teoride bir adet ResultSet'e hizmet verebilir. Statement kapandığı zaman, ona bağlı olan ResultSet de kapanır. Sıkıntı da aslında buradan kaynaklanıyor. Özellikle uzun sürede sonuç getiren bir sorgu çalıştırdığınız zaman Statement, uygulama sunucusunun pool ayarlarında tanımlı olan Statement Timeout'una takılıyor. Bu esnada Statement, uygulama sunucusu tarafından kapatıldığı için ResultSet nesnesi de kapanmış oluyor. Siz de herhangi bir veri çekmeye çalıştığınızda en tepede bahsettiğim hatayı alıyorsunuz.

Bu sorunu, SQL sorgunuzu optimize ederek ya da uygulama sunucusundaki kullandığınız veritabanı pool'unun Statement Timeout süresini uzatarak çözebilirsiniz. Glassfish için bu ayara "Resources > JDBC > JDBC Connection Pools > POOL_ADI > Advanced" menüsünden ulaşabilirsiniz.

java, jdbc, statement, resultset, pool, timeout, sqlexception, connection )

12 Aralık 2012 Çarşamba

Aspx Html Çift Title Sorunu

Aspx kullanarak oluşturulan web sitelerinde işimiz yarayan MasterPage'den kaynaklı olarak bir duplicate <title> tag problemi yaşıyor olabilirsiniz. Bunun başlıca sebebi, master sayfasının <head> tagleri arasında bulunan ContentPlaceHolder aslında. Her bir sayfada farklı bir title kullanmak istediğimizde <title>Sayfa Bilgisi</title> kodunu master sayfadaki <head> tagi arasına koymak yerine master sayfasındaki <head> tagi içerisine bir adet ContentPlaceHolder atarız. Sonrasında oluşturduğumuz sayfada bu ContentPlaceHolder'ın içeriğini koyacağımız yere <title> tagimizi koyarız. Bu işlem, sayfa render edildiğinde biri boş olmak üzere iki adet <title> tagine sebep olmaktadır. Bunun sebebi, server tarafında çalışan ve <head> içerisinde bulunan ContentPlaceHolder'ın, <title> tagini bulamayıp kendisinin ekstra bir adet daha üretmesidir.

Sorunun çözümü ise basit. Title bilgisini <title> tagi arasına koymak yerine sayfanın en tepesindeki <%@ Page Title=""... içerisine koymak. Sırasıyla sorunlu kod ve düzeltilmiş kod aşağıdaki gibi olmalıdır.

Hatalı Kod:
<%@ Page Title="" Language="C#" MasterPageFile="~/Mstr.master" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
    <title>BASLIK</title>
     ...
</asp:Content>


Doğru Kod:
<%@ Page Title="BASLIK" Language="C#" MasterPageFile="~/Mstr.master" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
    ...
</asp:Content>

( aspx, .net, <title>, <head>, çift title, contentplaceholder, masterpage, content, runat="server" )