除了使用標準的轉換器之外,您還可以自行定製您的轉換器,您可以實作 javax.faces.convert.Converter介面,這個介面有兩個要實作的方法:
public Object getAsObject(FacesContext context,
UIComponent component,
String str);
public String getAsString(FacesContext context,
UIComponent component,
Object obj);
簡單的說,第一個方法會接收從客戶端經由HTTP傳來的字串資料,您在第一個方法中將之轉換為您的自訂物件,這個自訂物件將會自動設定給您指定的Bean 物件;第二個方法就是將從您的Bean物件得到的物件轉換為字串,如此才能藉由HTTP傳回給客戶端。
直接以一個簡單的例子來作說明,假設您有一個User類別:
package onlyfun.caterpillar;
public class User { private String firstName; private String lastName;
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; } }
這個User類別是我們轉換器的目標物件,而您有一個GuestBean類別:
package onlyfun.caterpillar;
public class GuestBean { private User user; public void setUser(User user) { this.user = user; } public User getUser() { return user; } }
這個Bean上的屬性直接傳回或接受User型態的參數,我們來實作一個簡單的轉換器,為HTTP字串與User物件進行轉換:
package onlyfun.caterpillar;
import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.ConverterException;
public class UserConverter implements Converter { public Object getAsObject(FacesContext context, UIComponent component, String str) throws ConverterException { String[] strs = str.split(","); User user = new User(); try { user.setFirstName(strs[0]); user.setLastName(strs[1]); } catch(Exception e) { // 轉換錯誤,簡單的丟出例外 throw new ConverterException(); } return user; }
public String getAsString(FacesContext context, UIComponent component, Object obj) throws ConverterException { String firstName = ((User) obj).getFirstName(); String lastName = ((User) obj).getLastName(); return firstName + "," + lastName; } }
實作完成這個轉換器,我們要告訴JSF這件事,這是在faces-config.xml中完成註冊:
<?xml version="1.0"?> <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<faces-config> <navigation-rule> <from-view-id>/*</from-view-id> <navigation-case> <from-outcome>show</from-outcome> <to-view-id>/pages/index.jsp</to-view-id> </navigation-case> </navigation-rule> <converter> <converter-id>onlyfun.caterpillar.User</converter-id> <converter-class> onlyfun.caterpillar.UserConverter </converter-class> </converter>
<managed-bean> <managed-bean-name>guest</managed-bean-name> <managed-bean-class> onlyfun.caterpillar.GuestBean </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> </faces-config>
註冊轉換器時,需提供轉換器識別(Converter ID)與轉換器類別,接下來要在JSF頁面中使用轉換器的話,就是指定所要使用的轉換器識別,例如:
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@page contentType="text/html;charset=Big5"%>
<f:view>
<html> <head> <title>自訂轉換器</title> </head> <body>
Guest名稱是:<b> <h:outputText value="#{guest.user}" converter="onlyfun.caterpillar.User"/> </b>
<h:form> <h:inputText id="userField" value="#{guest.user}" converter="onlyfun.caterpillar.User"/> <h:message for="userField" style="color:red"/> <br> <h:commandButton value="送出" action="show"/> </h:form> </body> </html> </f:view>
您也可以<f:converter>標籤並使用converterId屬性來指定轉換器,例如:
<h:inputText id="userField" value="#{guest.user}">
<f:converter converterId="onlyfun.caterpillar.User"/>
</h:inputText>
除了向JSF註冊轉換器之外,還有一個方式可以不用註冊,就是直接在Bean上提供一個取得轉換器的方法,例如:
package onlyfun.caterpillar;
import javax.faces.convert.Converter;
public class GuestBean { private User user; private Converter converter = new UserConverter(); public void setUser(User user) { this.user = user; } public User getUser() { return user; } public Converter getConverter() { return converter; } }
之後可以直接結合 JSF Expression Language 來指定轉換器:
<h:inputText id="userField"
value="#{guest.user}"
converter="#{guest.converter}"/>
|