Struts(二十):自定义类型转换器
- 如何自定义类型转换器:
1)为什么需要自定义类型转化器?strtuts2不能自动完成字符串到所有的类型;
2) 如何定义类型转化器?
步骤一:创建自定义类型转化器的类,并继承org.apache.struts2.util..StrutsTypeConverter类;
步骤二:配置类型转化器(包含两种方式:基于字段的配置、基于类型的配置)
官网有类型转化器的写用法向导:http://struts.apache.org/docs/type-conversion.html
备注:从官网向导中我们知道struts2.3.13之后,是支持date类型自动转化的,看到官网上很多说date类型不可以自动转化的就需要看看文档了。
Built in Type Conversion Support
Type Conversion is implemented by XWork.
XWork will automatically handle the most common type conversion for you. This includes support for converting to and from Strings for each of the following:
- String
- boolean / Boolean
- char / Character
- int / Integer, float / Float, long / Long, double / Double
- dates - uses the SHORT format for the Locale associated with the current request
- arrays - assuming the individual strings can be coverted to the individual items
- collections - if not object type can be determined, it is assumed to be a String and a new ArrayList is created
Note that with arrays the type conversion will defer to the type of the array elements and try to convert each item individually. As with any other type conversion, if the conversion can't be performed the standard type conversion error reporting is used to indicate a problem occurred while processing the type conversion.
- Enumerations
- BigDecimal and BigInteger
- 基于字段的配置
1、在字段所在的Model(可能是Action,可能是一个JavaBean)的报下,新建一个ModelClassName-conversion.properties;
2、在ModelClassName-conversion.properties内输入键值对:fieldName=类型转换器的全类名;
3、加载时:第一次使用该转换器时创建实例;
4、类型转换器在使用过程中只实例化一次,是单例的。
基于上一篇文章《Struts(十九):类型转换、类型转换错误消息及显示》中例子上修改程序:
MyAction.java
/** * @author Administrator * */ package com.dx.actions; import java.awt.Point; import java.util.Date; import com.opensymphony.xwork2.ActionSupport; public class MyAction extends ActionSupport { private static final long serialVersionUID = 1L; private Integer age; private Date birth; private Point point; public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public Point getPoint() { return point; } public void setPoint(Point point) { this.point = point; } public String execute() { System.out.println("age:" + this.age + ",birth:" + this.birth + ",point:" + this.point); } }
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!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:debug></s:debug> <s:form action="myAction"> <s:textfield name="age" label="Age"></s:textfield> <s:textfield name="birth" label="BirthDay"></s:textfield> <s:textfield name="point" label="Point"></s:textfield> <s:submit label="提交"></s:submit> </s:form> </body> </html>
此时访问页面:index.jsp,提交表单会提示:
依照本小节的说明我们可以有两种方案配置方式来解决该问题:
新建一个conversion:com.dx.converters.PointConverter.java
package com.dx.converters; import java.awt.Point; import java.util.Map; import org.apache.struts2.util.StrutsTypeConverter; public class PointConverter extends StrutsTypeConverter { public PointConverter() { System.out.println("PointConverter's constructor..."); } @Override public Object convertFromString(Map context, String[] values, Class toClass) { System.out.println("convertFromString..."); if (toClass == Point.class) { if (values != null && values.length > 0 && values[0].indexOf(",") > 0) { try { int x = Integer.valueOf(values[0].split(",")[0]); int y = Integer.valueOf(values[0].split(",")[1]); return new Point(x, y); } catch (Exception ex) { ex.printStackTrace(); } } } return values; } @Override public String convertToString(Map context, Object o) { System.out.println("convertToString..."); if (o instanceof Point) { Point point = (Point) o; return point.getX() + "," + point.getY(); } return null; } }
解决方式一:
在MyAction.java包下创建一个MyAction-conversion.properties
point=com.dx.converters.PointConverter
解决方式二:
修改MyAction.java
/** * @author Administrator * */ package com.dx.actions; import com.dx.models.Member; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; public class MyAction extends ActionSupport implements ModelDriven<Member> { private static final long serialVersionUID = 1L; private Member member; public String execute() { System.out.println("age:" + member.getAge() + ",birth:" + member.getBirth() + ",point:" + member.getPoint()); return "success"; } @Override public Member getModel() { member = new Member(); return member; } }
新建com.dx.models.Member.java
/** * @author Administrator * */ package com.dx.models; import java.awt.Point; import java.util.Date; public class Member { private Integer age; private Date birth; private Point point; public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public Point getPoint() { return point; } public void setPoint(Point point) { this.point = point; } }
在com.dx.models包下创建Member-conversion.properties文件
point=com.dx.converters.PointConverter
- 基于类型的配置
1、在src下新建一个xwork-conversion.properties文件;
2、在文件xwork-conversion.properties中键入键值对:待转换的类型=类型转换器的全类名;
3、加载时:在当前struts2应用程序被加载时创建实例。
备注:因此如果在web.xml配置了context-param,读取参数时,需要通过get方法中获取,否则如果在constructor中获取context-param参数,将会导致读取不到context-param配置信息。
基于上边方案二修改出解决方案三:
1、把com.dx.models包下的Member-conversion.properties转移到工程根目录(目的使其不起作用),在src下创建文件xwork-conversion.properties
2、编辑文件xwork-conversion.properties内容
java.awt.Point=com.dx.converters.PointConverter
基础才是编程人员应该深入研究的问题,比如:
1)List/Set/Map内部组成原理|区别
2)mysql索引存储结构&如何调优/b-tree特点、计算复杂度及影响复杂度的因素。。。
3)JVM运行组成与原理及调优
4)Java类加载器运行原理
5)Java中GC过程原理|使用的回收算法原理
6)Redis中hash一致性实现及与hash其他区别
7)Java多线程、线程池开发、管理Lock与Synchroined区别
8)Spring IOC/AOP 原理;加载过程的。。。
【+加关注】。