1. JSF的转换器是在JSF生命周期的第2个阶段值应用请求和第6个阶段响应视图阶段。第二个阶段是将前台页面所有的String数据类型(HTTP提交后全都是字符串),按照绑定的托管值类型进行对应的值转换。第6个阶段与它正好相反,将处理完成后的托管Bean的绑定值再转换成字符串,呈献给前台页面。JSF自己默认有一些常用的数据转换类,比如数值型javax.faces.Integer、日期型javax.faces.DateTime、浮点型javax.faces.Double等等。在前台一般绑定的数据类型逃不出这一般的类型。我们这里只讨论自定义的数据类型转换器。
2. 有时候用一般类型还不能完全解决业务需要,我们要定义比较复杂的自定义类。那么JSF自己的转换器就不能帮您转换这个您自定义的类了,只能您自己定义一个转换器将其转换成您想要的那个样子。用一个网上最多的经典案例吧~~估计都用烂了~
首先定义一个业务Bean,它代表一个电话号码Bean。
PhoneNumberModel
package convert; /** * 电话号码模型 * @author 刘岩 */ public class PhoneNumberModel { private String areaCode; private String number; public String getAreaCode() { return areaCode; } public void setAreaCode(String areaCode) { this.areaCode = areaCode; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } @Override public String toString() { return areaCode + "-" + number; } }
之后定义一个转换器,需要实现javax.faces.convert.Converter接口,并且实现该接口的相关方法。
package convert; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.ConverterException; /** * 电话号码字符串转换类 * * @author 刘岩 */ public class PhoneNumber implements Converter { /** * 对应-应用请求值阶段 */ public Object getAsObject(FacesContext arg0, UIComponent arg1, String str) { if (str == null || "".equalsIgnoreCase(str)) { return null; } String[] strs = str.split("-"); PhoneNumberModel phoneNumberModel = new PhoneNumberModel(); try { phoneNumberModel.setAreaCode(strs[0]); phoneNumberModel.setNumber(strs[1]); } catch (Exception e) { e.printStackTrace(); FacesMessage message = new FacesMessage( FacesMessage.SEVERITY_ERROR, "电话号码转型出错", "标准:010-29890910"); throw new ConverterException(message); } return phoneNumberModel; } /** * 对应-数据呈现阶段 */ public String getAsString(FacesContext arg0, UIComponent arg1, Object obj) { // TODO Auto-generated method stub return obj.toString(); } }
getAsObject方法就是从界面获得String之后将此字符串做什么样的处理,转成让托管Bean能够认识的对象就行。getAsString方法是托管Bean执行完业务后返回给页面的值肯定是个String。其实这个转换器在这里做了一个不该自己做的事情就是实现了部分验证器的功能!当传过来的字符串不满足”XX-XX”这种形式就抛出了异常,并通知上下文,将错误消息传到上下文中,这样一旦检测到有错误,直接到生命周期的第六个阶段,呈现相应阶段。下面我们看看页面代码
<%@ page language="java" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> </head> <body> <f:view> <h:form id="guessForm"> <h2> 输入日期: </h2> <h:inputText id="dateId1" value="#{BeanBean.date}"> <f:convertDateTime pattern="yyyy-mm-dd" /> </h:inputText> <h:commandButton id="sumbit1" action="#{BeanBean.outDate}" value="提交日期" /> <br /> <h2> 输入电话: </h2> <h:inputText id="dateId2" value="#{BeanBean.phoneNumberModel}"> <f:converter converterId="convert.PhoneNumber" /> </h:inputText> <h:commandButton id="sumbit2" action="#{BeanBean.outPhoneNmber}" value="提交日期" /> <h:outputText value="#{BeanBean.phoneNumberModel}" /> <h:message for="dateId2" /> <br /> </h:form> </f:view> </body> </html>
其中输入电话使用的是自定义的验证器,日期是用的JSF默认的日期转换器,只是自己加了一个转换标准,按照”yyyy-mm-dd”样式输入,按照”yyyy-mm-dd”还给页面呈现。
托管Bean代码如下:
package model; import java.util.Date; import java.util.List; import convert.PhoneNumberModel; public class BeanBean { private String name; private int age; private List it; private Date date; private PhoneNumberModel phoneNumberModel; public BeanBean() { System.out.println(""); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public List getIt() { return it; } public void setIt(List it) { this.it = it; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public PhoneNumberModel getPhoneNumberModel() { return phoneNumberModel; } public void setPhoneNumberModel(PhoneNumberModel phoneNumberModel) { this.phoneNumberModel = phoneNumberModel; } public String outDate() { System.out.println(date.toString()); return "dateSys"; } public String outPhoneNmber() { System.out.println(phoneNumberModel.getAreaCode() + "-" + phoneNumberModel.getNumber()); return "dateSys"; } }
在JSF配置文件中加入如下配置,告诉JSF自定义的转换器
<!--定义转换器--> <converter> <converter-id>convert.PhoneNumber</converter-id> <converter-class>convert.PhoneNumber</converter-class> </converter>
执行效果如下
生命周期走完6个阶段,页面显示转换器转换对象后的正常电话号码
后台接到的日期结果为
Mon Jan 11 00:11:00 CST 1999 |