除了使用标准的转换器之外,您还可以自行定制您的转换器,您可以实作 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 类别:
- User.java
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 类别:
- GuestBook.java
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 物件进行转换:
- UserConverter.java
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 中完成注册:
- 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 页面中使用转换器的话,就是指定所要使用的转换器识别,例如:
- index.jsp
<%@ 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 上提供一个取得转换器的方法,例如:
- GuestBean.java
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}"/>