JSP提交的数据全部都是String类型的。struts2也是通过request.getParameter(name)获取到String类型数据,并通过拦截器将String转换成各种常用的数据类型,如:Date、Time、Timestamp等,然后通过getter、setter方法设置到Action对应的属性上。
struts2默认的转换器并不总是满足要求。例如:输入时间,struts2只能转换形如12:00:00的格式,而输入12:00就会抛错,也有一些数据类型struts2转换不了。因此,需要自定义数据转换器。
数据类型转换器都需要实现ognl.TypeConvertor接口。一般的,直接继承DefaultTypeConvertor类,并实现
convertValue(Map context,Object value,Class toType)方法就可以了。(DefaultTypeConvertor是位于ognl包下的,是ognl开源标准中的一部分。从此可以看出struts2集成了许多其他的技术。)
convertValue(Map context,Object value,Class toType)方法有三个参数,参数value为待转换的数据,参数toType为要转成的类型。注意JSP提交数据时,参数value为request.getParameterValues(String name)返回的String[]类型对象,而不是String。
===========================================
下面自定义一个日期、时间转换器。该转换器能够转换各种常用的时间格式。convertValue()方法既能将Date转换成String,也能讲String转换成Date。
==========================================
工作原理:
用户在convert.jap页面中输入要转换的内容后将请求提交,请求被提交到FilterDispatcher过滤器,FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(HttpServlet Request)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher则把请求的处理交给ActionProxy,ActionProxy通过Configuration Manager(struts.xml)询问框架的配置文件,加载一系列的拦截器,找到需要调用的Action类和相应的转换器,由拦截器将HttpServletRequest参数解析出来,传入Action,然后由action调用转换器进行数据转换处理。
==========================================
实现如下:
DateTimeConvertor.java
package com.lmb.struts2.convertor;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Map;
import ognl.DefaultTypeConverter;
public class DateTimeConvertor extends DefaultTypeConverter {
//日期格式转化器
private DateFormat[] dateFormat={
new SimpleDateFormat("yyyy-MM-dd"),//格式如2008-08-08
new SimpleDateFormat("yyyy/MM/dd"),//格式如2008/08/08
new SimpleDateFormat("yy-MM-dd"),//格式如08-08-08
};
//时间格式转化器
private DateFormat[] timeFormat={
new SimpleDateFormat("HH:mm:ssss"),//格式如13:00:1100
new SimpleDateFormat("HH:mm"),//格式如13:00
};
//重写转化方法
public Object convertValue(Map context,Object value,Class toType){
if(toType.equals(java.sql.Date.class)){//如果是java.sql.Date类型
String[] parameterValues=(String[])value;//原始字符串数据
for (DateFormat format:dateFormat) {//使用三种格式化其转化日期
try {
long n=format.parse(parameterValues[0]).getTime();
java.sql.Date date=new java.sql.Date(n);
return date;
} catch (ParseException e) {}
}
}else if (toType.equals(java.sql.Time.class)) {//如果是java.sql.Time类型
String[] parameterValues=(String[])value;//原始字符串数据
for (DateFormat format:timeFormat) {//使用2种格式化其转化时间
try {
long n=format.parse(parameterValues[0]).getTime();
java.sql.Time time=new java.sql.Time(n);
return time;
} catch (ParseException e) {}
}
}else if(toType.equals(java.util.Date.class)){//如果是java.util.Date类型
String[] parameterValues=(String[])value;//原始字符串数据
for (DateFormat format:dateFormat) {//使用三种格式化其转化日期
try {
java.util.Date date=format.parse(parameterValues[0]);
return date;
} catch (ParseException e) {}
}
}else if (toType.equals(String.class)) {//如果是字符串
if(value instanceof java.sql.Date){
}else if(value instanceof java.sql.Time){
}else if(value instanceof java.util.Date){
String str=dateFormat[0].format((java.util.Date)value);//将Date转换成字符串
return str;
}
}
return super.convertValue(context, value, toType);//否则调用父类方法
}
}
action类:
ConvertorAction.java
(通过为该action配置转换器来完成转换)
package com.lmb.struts2.action;
import com.opensymphony.xwork2.ActionSupport;
public class ConvertorAction extends ActionSupport{
private java.sql.Date sqlDate;
private java.sql.Time sqlTime;
private java.util.Date utilDate;
public java.sql.Date getSqlDate() {
return sqlDate;
}
public void setSqlDate(java.sql.Date sqlDate) {
this.sqlDate = sqlDate;
}
public java.sql.Time getSqlTime() {
return sqlTime;
}
public void setSqlTime(java.sql.Time sqlTime) {
this.sqlTime = sqlTime;
}
public java.util.Date getUtilDate() {
return utilDate;
}
public void setUtilDate(java.util.Date utilDate) {
this.utilDate = utilDate;
}
public String execute(){ //execute()主方法
return INPUT; //返回输入页面
}
public String convert(){ //convert()方法
return SUCCESS; //返回成功页面
}
}
下面为action配置以及为该action配置转换器的代码(注意属性名是converter,不是convertor)
struts.xml
name="convertor" class="com.lmb.struts2.action.ConvertorAction" converter="com.lmb.struts2.convertor.DateTimeConvertor">
<result name="success">/convertSuccess.jspresult>
<result name="input">/convert.jspresult>
转换器其配置有两种形式:
1、配置在xwork-conversion.properties中(对所有action都生效);
2、配置在struts.xml的action中(只对某一个action生效);
xwork-conversion.properties是又一个struts2的配置文件,只是名字上还保留着webwork的特征。同其它配置文件一样放置在“/WEB-INF/classes”下。Properties属性对的key为需要转化的类型,value为转换器的类名。该配置对所有的action都生效。另外转换器还可以配置只对某个action生效,即在struts.xml的action中进行配置。
在xwork-conversion.properties配置转换器的代码如下:
xwork-conversion.properties
java.sql.Date = com.lmb.struts2.convertor.DateTimeConvertor
java.sql.Time = com.lmb.struts2.convertor.DateTimeConvertor
java.util.Date = com.lmb.struts2.convertor.DateTimeConvertor
下面是input输入页面。页面中定义了3个日期输入域,用于输入不同格式的日期,例如2008/08/08、2008-08-08、12:00等,代码如下:
convert.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="struts" %>
<html>
<head>
<title>转换页面title>
head>
<body>
<struts:form action="convertor">
<struts:label label="转换器">struts:label>
<struts:textfield name="sqlDate" label="SQL Date:">struts:textfield>
<struts:textfield name="sqlTime" label="SQL Time:">struts:textfield>
<struts:textfield name="utilDate" label="Util Date:">struts:textfield>
<struts:submit value="提交" method="convert">struts:submit>
struts:form>
body>
html>
下面是success输出页面。该页面将转换成功的Date类型输出。在输出Action的Date类型属性时,struts2标签会再次调用转换器的convertValue()方法将Date类型转换成String类型,代码如下:
convertSuccess.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="struts" %>
<html>
<head>
<title>转换成功页面title>
head>
<body>
java.sql.Date:<struts:property value="sqlDate"/><br/>
java.sql.Time:<struts:property value="sqlTimee"/><br/>
java.util.Date:<struts:property value="utilDate"/><br/>
<a href="convertor.action"><<重新转换a>
body>
html>
如果输入非法的日期格式,将会转化为null,而不会抛出异常。以为异常在自定义转换器中用try……catch处理掉了,因此不会出现转化错误的页面。