JSF etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
JSF etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

Cuma, Kasım 20, 2009

JSF'te PDF Dosya Görüntüleme

Bir önceki kayıtta dosyaları servlet ile nasıl gösterebileceğimizi gösterdik. şimdi de aynı işi standart jsf yapısı içinde nasıl yapacağımıza bakalım. JSF ile pdf dosyası görüntlemek için button veya commandlink kullanabiliriz. ayrı bir sayfada açmak için target="_blank" yapılır.

public void showFile(){
try{
HttpServletResponse response = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
File file = new File(filePath+fileName);
BufferedInputStream input =new BufferedInputStream(new FileInputStream(file), 1024);

response.reset();
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "inline; filename=\"" + fileName + "\"");

BufferedOutputStream output = new BufferedOutputStream(response.getOutputStream(), 1024);
byte[] buffer = new byte[1024] //1KB buffer size
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
output.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
output.close();
input.close();
}catch(Exception e){e.printStackTrace();}
}
facesContext.responseComplete();
}


JSP sayfasında yapılması gereken de şöyle bir kod ile çağırmaktır;

<h:commandLink value="Download PDF" action="#{testBean.showFile}" target="_blank" />

Perşembe, Kasım 05, 2009

jsf de iframe yerine f:subview ile jsp:include kullanmak

iframe çok eski bir teknoloji. kullanıldığında beraberinde bir çok sorun getirebiliyor. onun için iframe kullanmaktan kaçınmak gerekiyor. jsf te iframe yerine f:subview ile jsp:inlcude kullanılabilir. çok basit bir şekilde aşağıdaki gibi kullanılabilir.
parent.jsp
<f:view>
...
<jsp:include page="child.jsp" />
...
</f:view>

child.jsp;
<f:subview id="child">
...
</f:subview>


f:subview yani child sayfasında eğer parent tan farklı bir bean kullanmak gerekirse o beanin request scope olması gerekiyor.

Salı, Ekim 27, 2009

rich:modalPanel ve rich:fileUpload

rich:fileUpload richfaces kütüphanesinde bulunan çok kullanışlı bir component. Fakat sayfa içinde biraz yer kapladığı için bazen modalpanel açıp onun içinde kullanmak gerekebilir.
rich:modalPanel içinde rich:fileUpload kullanmak için rich:modalPanel in form içinde olmaması gerekiyor. aynı zamanda modalpanel'in içinde fileupload'u içeren bir form olması gerekiyor. yoksa fileupload componenti çalışmaz. örnek kullanımı şöyle olabilir;
<h:form id="outform">
...
<a4j:commandButton value="Upload Excel File" id="fileuploadbutton">
<rich:componentControl for="fileuploadpanel" attachTo="fileuploadbutton" operation="show" event="onclick" />
</a4j:commandButton>
...
</h:form>
<rich:modalPanel id="fileuploadpanel" zindex="2000" autosized="true">
<f:facet name="header">
<h:outputText value="File Upload Panel"></h:outputText>
</f:facet>
<h:form id="fileuploadform">
<rich:fileUpload fileUploadListener="#{testBean.fileUploadListener}" acceptedTypes="csv" ontyperejected="alert('you can upload csv files');">
</rich:fileUpload>
...
</h:form>
</rich:modalPanel>

Çarşamba, Ağustos 05, 2009

jsf richfaces performance tuning

Jsf ve richfaces ile uygulama geliştirdiyseniz yavaşlık ile ilgili şikayetiniz olabilir. Bu teknolojiler dikkatli kullanılmadığında yavaşlık yaşayabilirsiniz. Aşağıda performans için yapılması gereken bir kaç şey eklenmiş.

Richfaces Filter
<filter>
<display-name>RichFacesFilter</display-name>
<filter-name>richfaces</filter-name>
<filter-class>org.ajax4jsf.Filter</filter-class>
<init-param>
<param-name>forceparser</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>enable-cache</param-name>
<param-value>true</param-value>
</init-param>
</filter>

enable-cache parametresi ile richfaces komponentlerini client tarafında cachelenmesini sağlar. bu sayede gözle görülür bir performans sağlanabilir. forceparser parametres ile de richfaces a sadece ajax geri dönüşleri düzenlemesini söylüyoruz. eğer bu parametreyi bu şekilde set etmezsek html dahil bütün geri dönüşleri düzenlemeye kalkar.

<context-param>
<param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name>
<param-value>true</param-value>
</context-param>

compress_script parametresi ile konteynır'a bütün richfaces kaynaklarını sıkıştırmasını söylüyoruz.

<!-- load all richfaces javascript onetime -->
<context-param>
<param-name>org.richfaces.LoadScriptStrategy</param-name>
<param-value>ALL</param-value>
</context-param>
<context-param>
<param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name>
<param-value>true</param-value>
</context-param>
<!-- load all richfaces css onetime -->
<context-param>
<param-name>org.richfaces.LoadStyleStrategy</param-name>
<param-value>ALL</param-value>
</context-param>


org.richfaces.LoadScriptStrategy parametresini ALL yapmakla bütün scriptleri ilk başta yüklemesini sağayabiliriz. böylelikle daha ilkin yavaşa yüklense de sonrasında uygulama hızlı bir şekilde çalışarak network trafğini azaltacaktır. aynı şekilde org.richfaces.LoadStyleStrategy parametresini ALL yaparak css lerinde ilk başta yüklemesini sağlayabiliriz.


Bunların dışında ajax kullanırken aşağıdaki durumlara dikkat etmekte fayda var;

-> herhangi bir partial rendering yaparken mutlaka ajaxSingle=true yu kullanmaya özen göstermek,

-> validasyonun gerekli olmadığı rendering durumlarında immediate=true yaparak hızlı bir şekilde cevap dönmesini sağlamak.

-> ajax response sonucunda sadece reRender="" litesini set edeceksek limitToList=true seçeneğini set ederek sadece ilgili alanların set edilmesini sağlamak.

-> ajax regionları kullanarak sadece ilgili region ın update edilmesini sağlamak. ajax region kullanırken renderRegionOnly yi true yaparsak sadece ilgili region update edilir.

-> jsf tagları ile halledilebilen bir işi richfaces tagı ile kullanmamak. örenğin h:datatable ile halledilebilecek bir iş için rich:datatable kullanmamak gerekiyor.

-> business logic kısmını getter lara koymamak.

Cuma, Temmuz 31, 2009

HttpSessionListener ve ServletContextListener

ServletContextListener ve HttpSessionListener bir web projesinde sıkça kullanılması gerekenlerdendir. bir web projesinde session create edilirken ve destroy olurken yapılması gereken işler mutlaka olur. Bunun için HttpSessionListener nesnesini kullanırız.

Aynı şekilde projeyi ilk olarak servera deploy edip başlatırken uygulamanın çalışması boyunca kullanılacak parametreleri yüklemek isteyebiliriz. veya uygulamayı kapatırken yapmamız gereken işler olabilir. Bu durumda contextlistenera ihtiyacımı olacaktır. Bunun için de ServletContextListener ı kullanabiliriz.

Aşağıda ikisini bir arada kullanan bir örnek bulunmaktadır.
public class MySessionListener implements HttpSessionListener, ServletContextListener {
public MySessionListener() {
}

public void sessionCreated(HttpSessionEvent event) {
/*session ilk oluşturulduğunda yapacağınız işleri burada yapabilirsiniz
örneğin aşağıda kullanıcı session objemizi oluşturup sessiona atıyoruz
*/
SessionUserBean sub =new SessionUserBean();
event.getSession().setAttribute("sessionUserBean", sub);
}

public void sessionDestroyed(HttpSessionEvent event) {
// session destroy olurken yapılmak istenen işler...
}

public void contextInitialized(ServletContextEvent event) {
//uygulama deploy edilirken yapılamsı gereken işler...
ApplicationBean appbean = new ApplicationBean();
event.getServletContext().setAttribute("applicationBean",appbean);

}


public void contextDestroyed(ServletContextEvent event) {
//uygulama kapatılırken yapılması gereken işler...
}
}


web.xml deki tanımı ise şöyle yapılabilir.
<!-- Session listeners -->
<listener>
<listener-class>org.yourapp.listener.MySessionListener</listener-class>
</listener>

Perşembe, Şubat 12, 2009

Ajax a4j:region

A4j:region ile sayfanızın hangi parçalarının ajax işlemi sırasında servera gideceğini belirlersiniz. Yani bir ajax request sırasında gerekli gereksiz sayfa nın tamamının servera gidip gelmesini ve bu şekilde trafik oluşmasını önlemiş oluruz. zaten ajax işlemlerinin hızlı gerçekleşmesi gerekiyor. eğer a4j:region gibi componentleri kullanıp sayfanın sadece ilgili kısmını göndermezsek sayfalar çok yavaş yüklenir ve networkte trafik oluşturur. Eğer region(servera gönderilecek alan) belirlenmezse f:view taglari arasındaki alanlar default region kabul edilir.
<f:view>
....
<a4j:region>
jsf komponentleri
</a4j:region>
....
</f:view>

Ajax a4j:outputPanel

a4j:outputPanel kendi içindeki componentlerin ajax responsunda render edilmesini sağlar. ayrıca outputpanel kendi içindeki componentlerin ajax işlemi sonunda rerender etme işleminde de kullanılır. ajaxRendered="true" kullandığınızda ajaxın rerender metoduna herhangi bir şey yazmanıza bile gerek kalmaz. şöyle ki;
<a4j:outputPanel 
ajaxRendered="true">
<h:panelGrid id="toppanelgrid" columns="2" width="750"
columnClasses="colStyle1,colStyle2">
<h:column>
<h:outputText value="Select One:"></h:outputText>
</h:column>
<h:column>
<h:selectOneMenu value="#{bean.selecteditem}"
required="true">
<f:selectItem itemLabel="Please Select" itemValue="" />
<f:selectItem itemLabel="item1" itemValue="item1" />
<f:selectItem itemLabel="item2" itemValue="item2" />
<a4j:support event="onchange" ajaxSingle="true"
actionListener="#{bean.itemrenderer}"></a4j:support>
</h:selectOneMenu>
</h:column>

<h:column rendered="#{bean.item1renderer}">
<h:outputText value="item1"></h:outputText>
</h:column>
<h:column rendered="#{bean.item1renderer}">
<h:inputText value="#{bean.item1text}"></h:inputText>
</h:column>

<h:column rendered="#{bean.item2renderer}">
<h:outputText value="item2"></h:outputText>
</h:column>
<h:column rendered="#{bean.item2renderer}">
<h:inputText value="#{bean.item2text}"></h:inputText>
</h:column>
</h:panelGrid>
</a4j:outputPanel>

Fakat önemli bir noktayı gözardı etmemek lazım. formunuzda ajaxRendered="true" olan birden fazla outputpanel iniz varsa bunların çalışması birbirini etkileyebilir. bu durumlarda rerender metodunu kullanmak gerekecektir.

Salı, Kasım 25, 2008

JSF te custom validation

Merhabalar,
jsf te validasyonların ne kadar kolay yapıldığını görelim istedim. normal bir jsf sayfasında hazır validasyonlardan;
f:validateLength
f:validateDoubleRange ve
f:validateLongRange kullanılarak girilen değerin uzunluk aralığını ve nullable ını kontrol edebiliriz.

örnek olarak;

vererek girilen değer aralığının 3 ile 15 arasında olmasını sağlarız.

asıl üzerinde duracağımız ise custom validasyonlar;
custom validasyon yazmak için tek yapmamız gereken Validator interface ini implement etmek. classı implement ettiğimizde validate metodunu da override etmemiz gerekir. ikinci adımda validasyon classımızı faces-config dosyasına yazıyoruz. üçüncü adımda ise kullanıyoruz. şöyle ki;

1.

package test.validator;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

public class AmountTypeValidator implements Validator {

public void validate(FacesContext arg0, UIComponent arg1, Object val) throws ValidatorException {
// TODO Auto-generated method stub
if ((val != null) && (!val.equals("select"))) {
return;
} else {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please Select Amount Type",
"Please Select Amount Type");
message.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(message);
}
}
}

eğer değerimiz null ise veya "select" ise o zaman uyarı veriyoruz.

2:

<validator>
<validator-id>AmountTypeValidator</validator-id>
<validator-class>test.validator.AmountTypeValidator</validator-class>
</validator>


3:

<h:selectOneMenu id="discountAmountType" required="#{testBean.amountTypeRequired}" value="#{testBean.selectedAmountType}">
<f:validator validatorId="AmountTypeValidator" />
<f:selectItem itemValue="select" itemLabel="Please Select" />
<f:selectItem itemValue="TRY" itemLabel="TRY" />
<f:selectItem itemValue="USD" itemLabel="USD" />
<f:selectItem itemValue="EUR" itemLabel="EUR" />
<f:selectItem itemValue="KILO" itemLabel="KILO" />
</h:selectOneMenu>

Cuma, Kasım 14, 2008

JSF rich:combobox problemi

sayfanızda daha güzel diye rich:combobox kullanmaya kalkışırsanız benim gibi neye uğradığınızı şaşırırsınız. çünkü rich:combobox value ve label değerini ayrı ayrı veremiyorsun. daha doğrusu label yok. sadece value değerini label olarak gösteriyor.
söz gelimi siz;

<rich:comboBox><f:selectItem itemValue="1" itemLabel="label1" />
<f:selectItem itemValue="2" itemLabel="label2" />
<f:selectItem itemValue="3" itemLabel="label3" />
<f:selectItem itemValue="4" itemLabel="llabel4" />
<f:selectItem itemValue="5" itemLabel="llabel5" />
</rich:comboBox>

yazdığınızda üretilen combobox ta label1 .. label5 görmeyi umuyorken 1,2..5 görürsünüz.

Bunu bir bug olarak yazmışlar jboss a ama bug değil kendi özelliği böyle. keşke bug olsaydıda düzeltilseydi. çünkü güzel özellikleri olan bir component.

ne diyelim clasik h:selectOneMenu ya devam :)