自定义类型转换器的作用就是将struts无法识别的类型转换成自己所需要的.
比如输入:广东-东莞-虎门,对应的输出时能输出:广东省 东莞市 虎门(镇/区)
这里涉及到的知识点即是将String转换为任意的JavaBean类型.
一.实现代码
程序配置入口:struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!--<include file="config/upload.xml"></include> --> <!-- 加载其他配置文件 --> <!-- <include file="config/upload-interceptor.xml"></include> --> <!-- 加载属性文件-国际化 --> <!-- <constant name="struts.custom.i18n.resources" value="message"></constant> --> <!-- 结果集 --> <!-- <include file="config/result_struts.xml"></include> --> <!-- 类型转换 --> <include file="config/type_struts.xml"></include> <!-- 文件下载 --> <!-- <include file="config/download_struts.xml"></include> --> </struts>
注:struts.xml是在项目运行的过程中被加载进入内存的,是项目配置的总入口,这里使用<include>属性加载外部的type_struts.xml
type_struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- <package name="type" extends="struts-default"> <action name="TypeAction" class="type.TypeAction" method="execute"> <result name="success" type="dispatcher"> /WEB-INF/type_success.jsp </result> <result name="input" type="dispatcher"> type.jsp </result> </action> </package> --> <package name="type" extends="struts-default"> <action name="TypeSelfAction" class="type.TypeSelfAction" method="execute"> <result name="success" type="dispatcher"> /WEB-INF/type_self_success.jsp </result> <result name="input" type="dispatcher"> /type_self.jsp </result> </action> </package> </struts>
注:type_struts.xml是具体负责类型转换时的配置,这里配置了对应的type.TypeSelfAction,以及成功后的跳转页面type_self_success.jsp和程序出错时
的跳转页面type_self.jsp,并将消息回显.
type_self.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:form action="TypeSelfAction" type="POST">
<s:textfield label="用户名" name="username" />
<s:password label="密码" name="password" />
<s:textfield label="薪水" name="salary" />
<s:textfield label="生日" name="birthday"/>
<s:textfield label="地址" name="address"/>
<s:submit value="提交" name="submit"/>
<s:reset value="重置"/>
</s:form>
</body>
</html>
注:type_self.jsp 是用户访问项目的入口,效果图如下所示:
其中使用POST请求方式是为了避免中文乱码等问题,使用struts自带的标签,如s:password,s:textfield等是为了简化开发,并且使错误消息方便回显.
TypeSelfAction.java
package type; import java.util.Date; import com.opensymphony.xwork2.ActionSupport; /** * @ClassName: TypeSelfAction * @Description: TODO * @author: amosli * @email:amosli@infomorrow.com * @date Feb 13, 2014 11:24:40 PM */ public class TypeSelfAction extends ActionSupport { private static final long serialVersionUID = -4007160582981636173L; private String username;// 用户名 private String password;// 密码 private Double salary;// 薪水 private Date birthday;// 生日 private Address address;// 地址 public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Address getAddress() { return address; } public void setAddress(Address address) { System.out.println("setaddress:"+address.toString()); this.address = address; } public String execute() throws Exception { return SUCCESS; } }
注:TypeSelfAction是一个与配置文件type_struts.xml相对应的JavaBean文件.
Address.java
package type; /** * @ClassName: Address * @Description: 定义一个address model * @author: amosli * @email:amosli@infomorrow.com * @date Jan 26, 2014 1:53:33 AM */ public class Address { private String province;// 省份 private String city;// 城市 private String area;// 区域 public Address(){ } public Address(String province, String city, String area) { super(); this.province = province; this.city = city; this.area = area; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getArea() { return area; } public void setArea(String area) { this.area = area; } public String toString() { return this.province+"省 "+this.city+"市 "+this.area+"(镇/区)"; } }
注:Address是关于地址的JavaBean,其分为省份,市,区域三级.
为了实现自定义类型转换还必须实现StrutsTypeConverter的扩展,这里要手动写两个方法将JavaBean转为String和将String转为JavaBean.
TypeAddressConverter.java
package type; import java.util.Map; import org.apache.struts2.util.StrutsTypeConverter; /** * @ClassName: TypeAddressConverter * @Description: 自定义类型转换器,继承自StrutsTypeConverter,可以将String转换成任意javaBean对象 * @author: amosli * @email:amosli@infomorrow.com * @date Feb 13, 2014 11:42:42 PM */ public class TypeAddressConverter extends StrutsTypeConverter { public TypeAddressConverter() { System.out.println("constructor!"); } //将String转为对象返回 public Object convertFromString(Map context, String[] values, Class toClass) { System.out.println("convertFromString"); // System.out.println("context:"+context); // System.out.println("class:"+toClass); // System.out.println("values:"+Arrays.toString(values)); if (Address.class == toClass) {// 判断类型是否为将要转成的JavaBean String[] split = values[0].toString().split("-");//页面中的字符串,下标为0表示第一个字符串,这里如果有多个可以依此类推. String province = split[0];// 省份 String city = split[1];// 市 String area = split[2];// 区 Address address = new Address(province, city, area); return address; } return null; } //将对象转为String返回 public String convertToString(Map context, Object o) { System.out.println("convertToString"); if (o instanceof Address) {// 判断对象类型是否为Adress Address adr = (Address) o; return adr.toString(); } return null; } }
注:这里是自定义类型转换的核心代码,即如何将一个JavaBean转为String和将String转为JavaBean.
为了调用上面的方法还必须加一个配置.
xwork-conversion.properties
#JavaBean=self defined typeconverter
type.Address=type.TypeAddressConverter
注:一般情况下应将xwork-conversion.properties存放在src目录下,我这里用的是Maven管理的,xwork-conversion.properties是放在resources目录下的,如下图所示:
自此所有配置结束.
二.效果图
1.点击提交按钮:
2.点击重置按钮: