uygulanan etiketler: java
pengeunpedi pengeunpedi pengeunpedi
  penguenyuvasi   pengulog   arşiv   bulut   rss

jsf / facelets'de kolay giriş ve güvenlik

Sunday, June 7, 2009 6:24:58 PM tarihinde Fırat KÜÇÜK tarafından gönderildi.

easy login and security in jsf / facelets.

Java Server Faces ile Uygulama yazarken daha önceki Ağ Çatılarında (Web Framework) kullandığımız alışılmış veritabanından kullanıcı adı / parola denetimi gibi özelliklerin daha farklı gerçeklendiğinin farkına vardım. Fakat yapmamız gereken basit kullanıcı adı ve parola denetimi ve oturum nesnesine kullanıcının sisteme giriş yaptığı bilgisinin yazılması.

Buraya kadar JSF ile sorunumuz yoktu fakat oturumu açmış kişilerin görüntüleyebileceği ve oturum açmamış kişilerin görüntülemek istediğinde giriş ekranına yönlendirildiği bir sayfa yapmak olabildiğince karmaşık görünüyor. Bazıları bu denetim için bir PhaseListener kullanıyor. Bazıları da ek JSTL etiketleri kullanmış bu nispeten bizim çözümümüze benziyor fakat 3. parti bir kütüphane daha eklememiz gerekiyor sisteme. Uygulama sunucusunun kullandığı güvenlik sistemi ve JAAS (Java Authentication and Authorization Service) kullananlar mevcut.

JSF'in bu konuda donatı (component) bazlı yaklaşmı oldukça güzel. Bu da olabildiğince gerekli bir durum elbetteki;

<h:outputText value="bu yazıyı yalnızca giriş yapmış kişiler görür" renderer="#{login.loggedIn}" />

Aynısının sayfa bazlı olanı da olsa tadından yenmez diyor insan :) Bu konuda f:view etiketinin beforePhase özelliği imdada yetişiyor. Ben de bu yaklaşımı kullandım.

Örnek uygulamayı bir facelets uygulaması olarak düşündüm. Ve açılma tanımlayıcısı (deployment descriptor) şu şekilde tanımlanıyor.

<?xml version="1.0" encoding="UTF-8"?>

<web-app>
  <context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.xhtml</param-value>
  </context-param>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>login.xhtml</welcome-file>
  </welcome-file-list>
</web-app>

Bu yapılandırma dosyasına göre;

- JSF'nin varsayılan uzantısı xhtml olarak seçiliyor.

- JSF'nin varsayılnan Servlet'i uygulama başlayınca başlatılıyor.

- Tüm xhtml uzantılı url'ler Faces Servletine yönlendiriliyor.

- Ve son alarakta uygulamamızın başlangıç dosyası login.xhtml olarak belirleniyor.

login.xtml betiğimizi tasarlıyalım:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
  <body>
    is logged in:  <h:outputText value="#{login.loggedIn ? 'yes' : 'no'}" />
    <h:form id="myForm">
      <h:commandButton id="buttonLogin" action="#{login.login}" value="login" />
      <h:commandButton id="buttonLogout" action="#{login.logout}" value="logout" />
    </h:form>
    <br />
    <a href="secure_page.xhtml" target="_blank">go the secure page</a>
  </body>
</html>

Bu sayfa çok basit olarak bir metin alan ve bir form içeriyor. Metin alan birazdan tanımlayacağımız login bean'e ait loggedIn özelliğini sorgulyor. UEL (Unified Expression Language) ile üçlü ternary operator kullanarak yazdığımız değer özelliği şöyle login bean'e ait loggedIn özelliği true ise yes metin değerini döndür eğer farklı ise no özelliğini döndür.

Sayfada bunun dışında bir form içinde iki form gönderme düğmesi bulunuyor. Birisi sisteme giriş yapmamızı sağlarken birisi de çıkış yapmamızı sağlıyor. Bu sayfada bolca adı geçen login bean'i tanımlayalım şimdi. Tabi login bean'i yazmadan evvel faces-config.xml dosyasında bu bean'i tanımlamalıyız.

<?xml version='1.0' encoding='UTF-8'?>

<faces-config version="1.2" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">

  <application>
    <view-handler>
      com.sun.facelets.FaceletViewHandler
    </view-handler>
  </application>

  <managed-bean>
    <managed-bean-name>login</managed-bean-name>
    <managed-bean-class>test.Login</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>

  <navigation-rule>
    <navigation-case>
      <from-outcome>not_authorized</from-outcome>
      <to-view-id>error.xhtml</to-view-id>
      <redirect />
    </navigation-case>
  </navigation-rule>

</faces-config>

Bu JSF yapılandırma dosyasında görünüm tutucu olarak bir Facelet Handler'ı kullanıyor bu facelets teknolojisini kullanmamız için gerekli bir yapılandırma yönetilmiş bean tanımlamızın yapıldığı etiketlere bakarsak bean'in adı login olarak belirtilmiş ve sınıf dosyası da test paketinin içerisindeki Login sınıfı olacak diye tanımlanmış buna ilaveten bu bean bir oturum alanında etkin diye belirtiyoruz. Bir yönetilmiş bean'in etki alanı oturum ise bir kullanıcı siteye girdiği anda talep ettiği sayfada bu bean kullanılıyor ise bir defaya mahsus sınıfın constructor'ı çağırılır ve sistemde sınıf örneği sonlandırılmadan bellekte kalır taki kullanıcı sistemden çıkana kadar veya oturum süresi eskiyene kadar.

Bu yaklaşım JSP'de olandan farklıdır. JSP'de SessionListener ile kullanıcı sisteme girdiği durumu denetleyebilirsiniz. ASP.NET'teki global.asax dosyasında belirttiğiniz Session_Start metodu gibi aslında fakat Java'da bir çok sınıf ve metod belirtebilirsiniz aynı anda. JSF'deki bean yaklaşımı ise daha kullanıcı dostudur.

package test;

import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;

public class Login {

  private boolean loggedIn;

  public Login() {
    loggedIn = false;
  }

  public boolean isLoggedIn() {
    return loggedIn;
  }

  public void setLoggedIn(boolean loggedIn) {
    this.loggedIn = loggedIn;
  }

  public String login() {
    loggedIn = true;
    return null;
  }

  public String logout() {
    loggedIn = false;
    return null;
  }

  public void checkLogin(PhaseEvent event) {

    if (!loggedIn) {
      FacesContext fc = event.getFacesContext();
      NavigationHandler nh = fc.getApplication().getNavigationHandler();
      nh.handleNavigation(fc, null, "not_authorized");
    }
  }
}

Login bean'de kullanıcının giriş yapıp yapmadığını tutan boolean loggedIn özelliği bulunuyor. Oturum başladığında bu bean'in yapıcı metodu olan Login() metodu çalışır ve loggedIn özelliğinin varsayılan değerini false yapar. Böylece sisteme girenlerin hepsi misafir durumunda olurlar.

login.xhtml dosyasında kullandığımız iki adet action metodu bulunuyordu. Yani iki adet form gönderim düğmesine bağlanmış login ve logout metodları. Bu JSF'in olay tabanlı bir çatı olmasından ileri gelmekte. Görünüm katmanındaki nesneleri denetim katmanındaki özellik veya metodlara bağlayabilmekteyiz. Bu action metodlarının String değer döndüğünü farketmişsinizdir. Eğer dönen değer faces_config.xml'deki bir dolaşım kuralına denk geliyor ise bu sayfaya yönlendirme yapılır. Eğer şu anda kullandığımız gibi bir null değer dönüyor ise aynı sayfaya geri döneceğizdir. Bu action metodları login.xhtml içerisinden çağrıldığı için aynı şekilde login veya logout işlemlerinden sonra tekrar login.xhtml sayfasına döneceğiz.

Buraya kadar uygulamamızı çalıştırıp oyanayabiliriz. login düğmesine bastığınızda "is logged in" yazısının yanında "yes" ifadesi yeralacaktır. logout düğmesine bastığınızda ise "no" ifadesi yeralacaktır. Yani sistemimiz büyük ölçüde çalışıyor. Sıra geldi secure_page.xhtml sayfamıza. Bu sayfa login olmuş kişilerin görebileceği çok gizli sayfamız.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core">
    <body>
      <f:view beforePhaseListener="#{login.checkLogin}">
        tebrikler...
      </f:view>
    </body>
</html>

Çok gizli bir sayfaya göre olabildiğince az kod içeriyor ama işlevi çok büyük :) Bu sayfada sizinde farkettiğiniz gibi en önemli alan beforePhaseListener özelliği ile login bean'e ait bir metodun bağlanması. Buradaki beforePhaseListener özelliği facelets'te an itibari ile olan bir bugdan dolayı bu şekilde isimlendirildi. JSF'teki orjinal hali beforePhase'dir. Bu nedenle facelets kullanarak uygulamayı geliştiren arkadaşlar beforePhaseListener yazmalılar. Sonuç olarak sayfa işlemeden önce login.checkLogin metodu çağrılır.

  public void checkLogin(PhaseEvent event) {

    if (!loggedIn) {
      FacesContext fc = event.getFacesContext();
      NavigationHandler nh = fc.getApplication().getNavigationHandler();
      nh.handleNavigation(fc, null, "not_authorized");
    }
  }

Bu metod eğer kullanıcı sisteme giriş yapmamış ise dolaşımı not_authorized olarak yönlendirir. not_authorized dolaşım etiketi faces-config.xml dosyasında error.xhtml dosyasına karşılık gelmektedir. Bu sayede eğer sayfaya izinsiz giriş yaptığınızda bu hata sayfasına yönlendirileceksiniz.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets">
  <body>
    YOU ARE NOT AUTHORIZED TO VIEW THIS PAGE
  </body>
</html>

Netice itibari ile basit bir login sistemini facelets veya JSF ile gerçekleştirmek için bu metod kullanılabilir. PhaseListener kullanıldığında sayfa url'lerin hepsini PhaseListener içerisinde belirtmeli veya buna özel bir mantık algoritması yapılmalıdır. Bu metod nispeten daha akılda kalıcı ve basit görünüyor. Spring çatısının bu konuda daha gelişmiş yaklaşımları bulunmakta. Daha gelişmiş bir güvenlik sistemi için Spring de kullanılabilir.

atölye, java, jsfkaynak | yorumlar [0]


tomcat'i ipv4 olarak çalıştırma

Sunday, May 3, 2009 2:53:21 PM tarihinde Fırat KÜÇÜK tarafından gönderildi.

Bazı uygulamalar varsayılan olarak ipv6 ağlar için etkinleştirilmiş olarak gelir. Bu nedenle az da olsa performans kayıpları yaşanabilir. Örneğin linux dağıtımınızda ipv6 açık ise /etc/modprobe.d/aliases dosyasından düzenleyebilirsiniz.

alias net-pf-10 off ipv6

Bu şekilde linux tüm ipv4 adresleri de ipv6 adreslerine çevirerek işlem yapmaktan vazgeçer. Fakat varsayılan olarak ipv6 ile işlem yapan servisler varsa bunlar için ilgili yapılandırma seçeneklerini ayarlamanız gerekecektir. Apache Tomcat için /bin/catalina.sh veya windows kullananlar /bin/catalina.bat dosyasının başına CATALINA_OPTS değişkenini ekleyebilirler. İsteyen kullanıcılar ise bunu çevresel değişken olarak tanıtabilirler. Ben kendi adıma daha kolay yol olan dosyaya ekleme metodunu tercih edicem. Linux kullanıcıları;

CATALINA_OPTS="-Djava.net.preferIPv4Stack=true"

şeklinde dosyanın 2. satırına ekleme yapabilirler. Tabiki ilk satırdaki (#!/bin/sh) ilişkilendirilmiş yorumlayıcıya müdahale etmemek gerekli. Bu nedenle 2. satıra yazmamız yeterli olacaktır.

Windows kullanıcıları ise aşağıdaki eklemeyi yapabilirler.

set CATALINA_OPTS=-Djava.net.preferIPv4Stack=true
java, sorun çözümükaynak | yorumlar [1]


telnet ile tomcat kapatma

Sunday, May 3, 2009 2:27:48 PM tarihinde Fırat KÜÇÜK tarafından gönderildi.

Apache Tomcat belgelerini incelerken server.xml ayar dosyasının üst seviye elemanı olan Server etiketine ait shutdown adlı bir özellik olduğunu farkettim. Evet tomcat'e ait bir kapatma portu bulunuyormuş. Bu shutdown özelliği ile de kapatırken Tomcat'e ileteceğiniz komut bulunuyor. Varsayılan olarak ayar şu şekilde:

<Server port="8005" shutdown="SHUTDOWN">

Bu demek oluyor ki 8005 portuna SHUTDOWN verisi yollarsak tomcat kapatma işlemini başlatacaktır. Bu port varsayılan olarak yerel döngü (local loopback) üzerinde çalışyor. Ama iptables yönlendirmeleri ile kendi ağınızdan tomcat'i kapatabileceğinizi ön görüyorum.

# telnet localhost 8005
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SHUTDOWN
Connection closed by foreign host.
inceleme, javakaynak | yorumlar [0]


jsf akıllı mbean yükleme mekanizması

Sunday, May 3, 2009 8:26:16 AM tarihinde Fırat KÜÇÜK tarafından gönderildi.

JSF çatısında bir POJO (Plain Old Java Object - Bildiğiniz Sıradan Java Nesnesi) oluşturarak MVC paradigmasının model kısmını oluşturabilmektesiniz. Bu ASP.NET çatısında codebehind olarak geçiyor. JSF'te Codebehind'a tam karşılık gelen kavram ise backing bean kavramı Buna ilaveten POJO'lar veritabanı varlıklarında (JPA Entities) ve diğer tüm bean çeşitlerinde kullanılabilmekte.

JSF'te bir backing bean yazarken en çok aklıma takılan husus beanlerin küresel olarak tanımlanması idi. faces-config.xml dosyasına örnek bir kaç bean tanımlayalım;

  <managed-bean>
    <managed-bean-name>requestBean1</managed-bean-name>
    <managed-bean-class>rtest.RequestBean1</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>

  <managed-bean>
    <managed-bean-name>requestBean2</managed-bean-name>
    <managed-bean-class>rtest.RequestBean2</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>

  <managed-bean>
    <managed-bean-name>requestBean3</managed-bean-name>
    <managed-bean-class>rtest.RequestBean3</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>

Şüphelerim şu yöndeydi; Bir talep esnasında tüm bu bean'ler işleniyor muydu? Eğer böyle ise karmaşık bir sitede onlarca hatta yüzlerce request alanında bean olabilirdi. Ve kullanılmayacak olan bir çok bean gereksiz yere RAM alanına aktarılacak ve sistem kaynaklarını kullanacaktı. Bunu yapıcıya basit bir çıktı ifadesi yazarak test ettim.

package rtest;

public class RequestBean1 {

  private String test;

  public RequestBean1() {
    System.out.println("----------------------------------------------");
    System.out.println("RequestBean1");
  }

  public String getTest() {
    return test;
  }

  public void setTest(String test) {
    this.test = test;
  }
}

JSF sayfamızda şu şekilde:

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<f:view>
</f:view>

Senaryoya göre eğer bir yükleme olacak ise bean başlatılıp yapıcı metodu çalıştırılacak ve sunucu loglarında çıktıyı görebileceğiz. Netice itibari ile bu gerçekleşmedi. Şimdi bean'e talepte bulunulacak şekilde JSF sayfasının fview kısmını değiştirelim.

<f:view>
  <h:outputText value="#{requestBean1.test}" />
</f:view>

Şimdi sunucu loglarında görüntüleme sağlayabildik. Netice itibari ile JSF geliştiricilerinin yapmış olduğu akıllı yükleme sayesinde kaynak tüketiminin önüne geçilmiş omakla beraber hızlı uygulama geliştirme paradigmalarından da ödün vermemiş oluyoruz. Buna ilaveten bir hatırlatma yapmakta fayda var. Eğer bir bean kullanıyorsanız. Bunun çalışma alanını olabildiğince düşük seçmeniz mantıklı olacaktır. request alanında (scope) yapılacak bir işlemin session veya application ile yapılması kaynak tüketimini doğrudan etkileyecektir.

inceleme, java, jsfkaynak | yorumlar [0]


uzun bir bekleyişten sonra

Sunday, September 14, 2008 10:07:21 AM tarihinde Fırat KÜÇÜK tarafından gönderildi.

Yaklaşık 1 senedir bu günlüğüme yazı yazmıyordum. 2009 yılının yaklaşması itibari ile penguenyuvasi.org için tamamen yerli üretim bir blog çalışması içerisine girdim. Sözü fazla uzatmadan kısmet bugüneymiş diyorum. :)

Penguenyuvası'nda neler yapıldı ve neler yeni?

Öncelikle tüm görsel öğeler inkscape ve gimp kullanılarak tek tek el ile hazırlandı. Tabi yuvarlak hatlı penguenler oldu biraz ama neyse :)

Kodlama kısmını başta PHP ve codeigniter kullanarak gerçekleştirdim. (PHP ile proje yapacaklara tavsiyem codeigniter veya symfony'i mutlaka denemeleri.) Ama sonra beni tanıyanlar bilirler 2 hafta önce canım sıkıldı ve kalan kısmını PHP ile devam etmek yerine tamamen Java'da yazmanın daha mantıklı olacağını düşündüm her nasılsa???

Kodlama esnasında kullandığım teknolojiler şunlar:

  1. Düzenleyici ve IDE olarak: netbeans 6.1, vim, gedit
  2. Veritabanı: MySQL (5.0.51a-3ubuntu5.1)
  3. Sunucu: Ubuntu 7.10 üzerinde Apache 2.2.4-3ubuntu0.1 ve Apache Tomcat 6.0.18
  4. Programlama dili: Java
  5. Alt teknolojiler: Java Bean, Filter, Servlet, Jspx, Jspf, Tag handler, Tagx, TLD'ler

Kodlama esnasında kendime bir projenin Java'dan PHP'e dönüştürülmesinin çoka akıllı bir davranış olmadığı konusunda bir çok telkinde bulundum, hatta zaman zaman kendime küfrettim. PHP'de tek metod ile yapacağınız bir şey için Java'da 3-4 satır kod yazmanız kaçınılmaz. Fakat Java teknolojilerinde daha çok detaya inmek mümkün. Sunucu ile ilişkileriniz daha sıkı.

Sıkı ilişki kelimesini açarsak web sunucu ve web sunucu üzerinde çalışan uygulamalar, aynı dilde yazıldığından bu bir avantaj. Bir kaç örnek verelim Servlet dediğimiz web uygulamacığı çalışmadan önce veya çalıştıktan sonra gelen ve gönderilen parametreleri bir süzgeçten (javax.servlet.Filter) geçirebiliyorsunuz. Bu da sizin PHP'de yalnızca Apache'ye modül yazarak gerçekleştirebileceğiniz işleri yapmanıza imkan tanıyor.

<filter>
  <filter-name>Suzgec</filter-name>
  <filter-class>org.pengulab.penguenyuvasi.filters.PenguFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>Suzgec</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Url örüntülerini (url-pattern) kolayca yönlendirebilmemiz (servlet-mapping) de bir avantaj. Örneğin tüm .pengu uzantılı dosyalara Pengu servlet'inin cevap vermesini sağlıyabiliriz. Böylelikle kendi şablon dilimizi hatta web üzerinde çalışan betik programlama dilimizi yapmamızı sağlar. (Javy webde böyle çalışıyor şuanda)

<servlet>
  <servlet-name>Pengu</servlet-name>
  <servlet-class>org.pengulab.penguenyuvasi.handlers.PenguHandler</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>Pengu</servlet-name>
  <url-pattern>/*.pengu</url-pattern>
</servlet-mapping>

Bunu Apache'de yapmak için bir Tutucu (Handler) yazmamız lazım. Bu Handler'ı .htaccess dosyasında veya genel yapılandırma dosyasında tanımlarız. Apache'nin bütünleşik veya modüllerinde gelen tutucularına ilaveten Java'da olduğu gibi bir tutucu yapmak için Action komutunu kullanıyoruz. (wepy'de bu şekilde çalışıyordu.)

Action add-footer /cgi-bin/footer.pl
AddHandler add-footer .html

Tekrar kullanılabilir öğeler (reusable components) yapma konusunda ise Java oldukça yetenekli tag, tagx dosyaları ile tld kütüphaneleri ile kendi özelleştirilmiş xml etiketlerinizi oluşturabiliyorsunuz. Hatta javanın ifade dili (EL - Expression Language) için işlevlerde yazabiliyorsunuz bu sayede.

penguenyuvasi.org'da neler yeni sorusunun cevabına gelirsek uzun bir zamandır viki imlası ile günlük girdisi yazma hayalim vardı. Bu hayali yeni sürüm ile gerçekleştirdim. Pegi adını verdiğim viki imlası ayrıştırıcısını kullanarak daha kolay ve anlaşılır gönderiler yazmak mümkün. Bir de şirin mi şirin etiket bulutumuz var. Bu da web 2.0'ın nimetlerinden. Gerçi yeni trend bildiğiniz gibi RIA (Rich Internet Applications) yani janjanlı flex, ajax, silverlight sayfaları. Bu uygulamalar internetin yakın gelecekteki hali hakkında ipuçları veriyor. Sanırım HTML artık flash veya applet gibi öğeleri içene gömmekte kullandığımı 4 - 5 satırlık bir geleceğe doğru gidiyor.

Karşılaşılan zorluklar

Java denilince akla yerel problemi geliyor. Oldukça sık karşılaştığım canım Türkçeme yapılan eziyetler'den kurtulamadım bir türlü. Forward ve include'a ait parametrelerde kullandığınız Türkçe karakterler bozuk gönderilmekte. Bu nedenle:

request.setCharacterEncoding("UTF-8");

ifadesi ise bu durumun çaresi fakat her betiğe tek tek yazmak zor olacağı için filter çözümü daha uygun gibi:

import java.io.*;
import javax.servlet.*;

public class EncodingFilter implements Filter {

  private String encoding;

  public void destroy() {
  }

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    request.setCharacterEncoding((encoding == null || encoding.isEmpty()) ? "UTF-8" : encoding);
    chain.doFilter(request, response);
  }

  public void init(FilterConfig config) throws ServletException {
    encoding = config.getInitParameter("encoding");
  }
}

web.xml dosyasınada şu şekilde girdide bulunabiliriz.

<filter>
  <filter-name>EncodingFilter</filter-name>
  <filter-class>org.pengulab.penguenyuvasi.filters.EncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>EncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Bunun daha kısa bir yolu varsa önerileri bekliyorum. Diğer bir yerel problemi ise veritabanına yaptığımız sorgularda baş gösteriyor. Bunu düzeltmemiz için JDBC bağlantı dizgesinin sonuna ek iki adet parametre eklememiz gerekli:

jdbc:mysql://localhost:3306/veritabani?characterEncoding=utf8&useUnicode=true
atölye, haber, inceleme, java, php, sorun çözümükaynak | yorumlar [0]




<<  1  2  3  4  >  >>  


pengulog

her hakkı erkektir © 2008 e-posta