JSF提供了大量的转换器可拱我们选择,但有的时候程序员们往往需要自己来自定义一些转换器来完成一些特定的功能。下面的示例就讲解如何在JSF中进行自定义转换器。
本例对用户在客户输入的一个号码,国家号码-区号-号码,这样的格式进行分解及转换,最后固定的格式输出到客户端。
一、 电话号码类
客户所输入的一串数字,由于采用”-“进行连接,因此只能存为一串string,此时可以采用自己定义的转换器进行格式转换(当然,读者也许能找到现成的转换器,但本例在于说明如何自定义转换器)。
先定义电话号码类:PhoneNumber.java
package
com.sterning.converters;

import
java.io.Serializable;

public
class
PhoneNumber
implements
Serializable

{
private int countryCode;
private int areaCode;
private long number;

public PhoneNumber()

{
}

public PhoneNumber(int countryCode, int areaCode, long number)

{
this.setCountryCode(countryCode);
this.setAreaCode(areaCode);
this.setNumber(number);
}

public int getCountryCode()

{
return countryCode;
}

public void setCountryCode(int countryCode)

{
this.countryCode = countryCode;
}

public int getAreaCode()

{
return areaCode;
}

public void setAreaCode(int areaCode)

{
this.areaCode = areaCode;
}

public long getNumber()

{
return number;
}

public void setNumber(long number)

{
this.number = number;
}
}
二、 定义转换器
所有的转换器必须实现接口Converter
,同时必须重写getAsObject()
和 getAsString()
方法。getAsObject()方法在用户输入了合法的数据,并按下提交按钮后触发。getAsString()在渲染阶段触发,主要用于向客户展示数据。
package
com.sterning.converters;

import
java.util.StringTokenizer;
import
javax.faces.component.UIComponent;
import
javax.faces.context.FacesContext;
import
javax.faces.convert.Converter;
import
javax.faces.convert.ConverterException;

public
class
PhoneNumberConverter
implements
Converter

{

public PhoneNumberConverter()

{
}

public Object getAsObject(FacesContext context, UIComponent component, String value)

{

if (value == null || (value.trim().length() == 0))

{
return value;
}

PhoneNumber phoneNumber = new PhoneNumber();
boolean conversionError = false;

int hyphenCount = 0;
StringTokenizer hyphenTokenizer = new StringTokenizer(value, "-");
while (hyphenTokenizer.hasMoreTokens())

{
String token = hyphenTokenizer.nextToken();
try

{
if (hyphenCount == 0)

{
phoneNumber.setCountryCode(Integer.parseInt(token));
}

if (hyphenCount == 1)

{
phoneNumber.setAreaCode(Integer.parseInt(token));
}

if (hyphenCount == 2)

{
phoneNumber.setNumber(Long.parseLong(token));
}
hyphenCount ++;
}
catch (Exception exception)

{
conversionError = true;
}
}

if (conversionError || (hyphenCount != 3))

{
throw new ConverterException();
}

return phoneNumber;
}

public String getAsString(FacesContext context, UIComponent component, Object value)

{
PhoneNumber phoneNumber = null;

if (value instanceof PhoneNumber)

{
phoneNumber = (PhoneNumber)value;

StringBuilder phoneNumberAsString = new StringBuilder();
phoneNumberAsString.append(phoneNumber.getCountryCode() + "-");
phoneNumberAsString.append(phoneNumber.getAreaCode() + "-");
phoneNumberAsString.append(phoneNumber.getNumber());
return phoneNumberAsString.toString();
}
return "";
}
}


三、 Bean类
这里做的事情比较简单,将用户输入的非格式的电话号码,按一定的格式在客户端展示出来。
package
com.sterning.converters;

import
java.util.
*
;
import
javax.faces.application.
*
;
import
javax.faces.component.
*
;
import
javax.faces.component.html.
*
;
import
javax.faces.context.
*
;
import
javax.faces.event.
*
;

import
com.sterning.converters.PhoneNumber;

public
class
PhoneNumberBean

{
private HtmlPanelGrid controlPanel;
private PhoneNumber phoneNumber;

public HtmlPanelGrid getControlPanel()

{
return controlPanel;
}

public void setControlPanel(HtmlPanelGrid controlPanel)

{
this.controlPanel = controlPanel;
}

public void addControls(ActionEvent actionEvent)

{
UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
Application application = FacesContext.getCurrentInstance().getApplication();
List children = controlPanel.getChildren();
children.clear();

HtmlOutputText out1=(HtmlOutputText)application.createComponent(HtmlOutputText.COMPONENT_TYPE);
out1.setValue(" " + phoneNumber.getCountryCode() + " ");
out1.setStyle("color: blue");
children.add(out1);
HtmlOutputText out4=(HtmlOutputText)application.createComponent(HtmlOutputText.COMPONENT_TYPE);
out4.setValue(" - ");
out4.setStyle("color: blue");
children.add(out4);
HtmlOutputText out2=(HtmlOutputText)application.createComponent(HtmlOutputText.COMPONENT_TYPE);
out2.setValue(" " + phoneNumber.getAreaCode() + " ");
out2.setStyle("color: blue");
children.add(out2);
HtmlOutputText out5=(HtmlOutputText)application.createComponent(HtmlOutputText.COMPONENT_TYPE);
out5.setValue(" - ");
out5.setStyle("color: blue");
children.add(out5);
HtmlOutputText out3=(HtmlOutputText)application.createComponent(HtmlOutputText.COMPONENT_TYPE);
out3.setValue(" " + phoneNumber.getNumber() + " ");
out3.setStyle("color: blue");
children.add(out3);

}


public PhoneNumber getPhoneNumber()
{
return phoneNumber;
}


public void setPhoneNumber(PhoneNumber phoneNumber)
{
this.phoneNumber = phoneNumber;
}
}
四、 注册转换器
在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
>
<
converter
>
<
description
>
A Converter for phone number
</
description
>
<
converter-id
>
PhoneNumberConverter
</
converter-id
>
<
converter-class
>
com.sterning.converters.PhoneNumberConverter
</
converter-class
>
</
converter
>


<
managed-bean
>
<
description
>
The one and only phoneNumberBean.
</
description
>
<
managed-bean-name
>
phoneNumberBean
</
managed-bean-name
>
<
managed-bean-class
>
com.sterning.converters.PhoneNumberBean
</
managed-bean-class
>
<
managed-bean-scope
>
session
</
managed-bean-scope
>
</
managed-bean
>

</
faces-config
>
同时,别忘了配置web.xml哦
<?
xml version="1.0" encoding="UTF-8"
?>
<!
DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"
>

<
web-app
>
<
display-name
>
JSF
</
display-name
>
<
servlet
>
<
servlet-name
>
Faces Servlet
</
servlet-name
>
<
servlet-class
>
javax.faces.webapp.FacesServlet
</
servlet-class
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>
Faces Servlet
</
servlet-name
>
<
url-pattern
>
/faces/*
</
url-pattern
>
</
servlet-mapping
>
<
welcome-file-list
>
<
welcome-file
>
faces/index.jsp
</
welcome-file
>
</
welcome-file-list
>
</
web-app
>
五、 编写页面
Index.jsp页面比较简单:如下
<%
@page pageEncoding
=
"
UTF-8
"
contentType
=
"
text/html; charset=UTF-8
"
%>
<%
@ taglib uri
=
"
http://java.sun.com/jsf/core
"
prefix
=
"
f
"
%>
<%
@ taglib uri
=
"
http://java.sun.com/jsf/html
"
prefix
=
"
h
"
%>

<
f:view
>
<
html
>
<
head
>
<
title
>
JSF自定义转换器示例
</
title
>
</
head
>
<
body
>
<
h:form id
=
"
welcomeForm
"
>
<
h:outputText id
=
"
welcomeOutput
"
value
=
"
JSF自定义转换器示例!
"
style
=
"
font-family: Arial, sans-serif; font-size: 24; color: green;
"
/>
<
p
>
<
h:message id
=
"
errors
"
for
=
"
helloInput
"
style
=
"
color: red
"
/>
</
p
>
<
p
>
<
h:outputLabel
for
=
"
helloInput
"
>
<
h:outputText id
=
"
helloInputLabel
"
value
=
"
请输入一个完整的电话,(国家代码-区号-号码):
"
/>
</
h:outputLabel
>
<
h:inputText id
=
"
phoneNumberInput
"
value
=
"
#{phoneNumberBean.phoneNumber}
"
required
=
"
true
"
>
<
f:converter converterId
=
"
PhoneNumberConverter
"
></
f:converter
>
</
h:inputText
>

<
h:commandButton id
=
"
redisplayCommand
"
type
=
"
submit
"
value
=
"
提交
"
actionListener
=
"
#{phoneNumberBean.addControls}
"
/>
</
p
>
<
p
>
<
h:panelGrid id
=
"
controlPanel
"
binding
=
"
#{phoneNumberBean.controlPanel}
"
columns
=
"
20
"
border
=
"
1
"
cellspacing
=
"
0
"
/>
</
p
>


</
h:form
>
</
body
>
</
html
>
</
f:view
>

参考文献:http://www.javabeat.net/articles/2007/11/using-converters-in-jsf/3