(七)struts2之自定义类型转换器
来源:互联网 发布:淘宝开个店铺多少钱 编辑:程序博客网 时间:2024/05/17 20:02
一、概述
在B/S应用中,将字符串请求参数转换为相应的数据类型,是MVC框架提供的功能,而Struts2是很好的MVC框架实现者,理所当然,提供了类型转换机制。
Struts2的类型转换是基于OGNL表达式的,只要我们把HTML输入项(表单元素和其他GET/POET的参数)命名为合法的OGNL表达式,就可以充分利用Struts2的转换机制。
除此之外,Struts2提供了很好的扩展性,开发者可以非常简单的开发自己的类型转换器,完成字符串和自定义复合类型之间的转换。总之,Struts2 的类型转换器提供了非常强大的表现层数据处理机制,开发者可以利用Struts2的类型转换机制来完成任意的类型转换。
WEB应用接收到表单提交的数据都是String类型的,Struts2可方便的转换为 常规类型(数值,日期) / 自定义类型(User,Point类).
如果转换中出现异常,conversionError拦截器会自动处理该异常.
二、 常规类型的转换
比如表单提交的信息有 用户名,生日, 年龄, Action中对应的数据类型分别是 String, Date, int. 没什么好说的, Struts2会自动完成.
Struts2内建了常用的类型转换器,如String ,boolean,char,int,long,float,double,Date, 数组(假定元素是String类型), 集合(假定元素是String类型,用ArrayList封装)
三、页面中常用类型的OGNL表达式写法
在html表单中的文本框里输入的不管是数值类型还是字符类型,最后都是以String类传到后台。如果后台bean的属性是int、double、Date等,Struts就会自动把字符类型转换成相应的类型。
Struts2中默认提供了一些内置的转换器,包括8个基本类型,Date,array数组,List,Map类。也可以自定义转换器。通过实现ogln.TypeConverter接口实现它的方法就可以定义其他类型的转换,不过还要配置相应的资源文件。其实那几个内置的转换器已经足够使用了,很少会专门定义一个转换器。
基本数据类型转换器没有什么特殊要求,只要输入的值符合基本数据类型,它都会自动转换,否则会出现错误提示。比如对于int类型,前天就不能输入跟数字无关的字符。再来就是日期类型,默认好像是YY-MM-DD,比如2008-8-8,如果写成8-8-2008提交后就会出现错误提示。
对于Array数组,List,Map则需要配合OGNL表达式一起使用。比如后台有个属性是String [] name,在前台界面
<s:textfield name="names[0]" label="names"/>
<s:textfield name="names[1]" label="names"/>
<s:textfield name="names[2]" label="names"/>
就会对这个数组赋值。List跟数组使用方式一样,但只针对不加泛型的基本数据类型的的List,如果加了泛型则是
<s:textfield name="users[0].username" label="Usernames"/>
<s:textfield name="users[1].username" label="Usernames"/>
<s:textfield name="users[2].username" label="Usernames"/>
比如User类中有个username属性,List<User> users这个属性对应上面的写法。
最后是Map的转换方式
<s:textfield name="maidenNames['beth']" label="Maiden Name"/>
<s:textfield name="maidenNames['sharon']" label="Maiden Name"/>
<s:textfield name="maidenNames['martha']" label="Maiden Name"/>
[]里的值对应到Map中的Key
四、自定义类型转换器
实现TypeCoverter接口,或者继承DefaultTypeConverter实现类(该类实现了TypeCoverter接口),通过继承该实现类来实现自己的类型转换器。重写convertValue方法即可。
为了简化类型转换器的实现,Struts2提供了一个StrutsTypeConverter抽象类,这个抽象类是DefaultConverter的子类。实现了方法,并提供了2个不同转换方向的方法:Object
convertToString(Map context,String[] values,Class toClass)和String convertFromString(Map context,Object o)。
具体使用步骤:
1)注册应用
实现了自定义类型转换器之后,将该类型转换器注册在Web应用中,Struts2框架才可以正常使用该类型转换器。
关于类型转换器的注册方式,主要有3中:
A、注册局部类型转换器:仅仅对某个Action的属性起作用。
B、注册全局类型转换器:对所有Action的特定类型的属性都会生效。
C、使用JDK1.5的注释来注册类型转换器:通过注释方式来生成类型转换器。
2)局部类型转换器
提供如下格式的文件
文件名: ActionName-conversion.properties
内容:多个propertyName(属性名)=类型转换器类(含包名),如 date=com.aumy.DateConverter
存放位置:和ActionName类相同路径。
3)全局类型转换器
提供如下格式的文件
文件名: xwork-conversion.properties
内容: 多个“复合类型=对应类型转换器”项组成,如 java.Util.Date=com.aumy.DateConverter
存放位置:WEB-INF/classes/目录下。
应用示例
先看几个实体类
User.java
- <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.domain;
- import java.util.Date;
- public class User {
- private Integer id;
- private String loginname;
- private Double score;
- private Character cha;
- private Date birthday;
- private Gender gender;
- public User(){}
- public User(Integer id, String loginname, Double score, Gender gender,
- Character cha, Date birthday) {
- this.id = id;
- this.loginname = loginname;
- this.score = score;
- this.gender = gender;
- this.cha = cha;
- this.birthday = birthday;
- }
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getLoginname() {
- return loginname;
- }
- public void setLoginname(String loginname) {
- this.loginname = loginname;
- }
- public Double getScore() {
- return score;
- }
- public void setScore(Double score) {
- this.score = score;
- }
- public Gender getGender() {
- return gender;
- }
- public void setGender(Gender gender) {
- this.gender = gender;
- }
- public Character getCha() {
- return cha;
- }
- public void setCha(Character cha) {
- this.cha = cha;
- }
- public Date getBirthday() {
- return birthday;
- }
- public void setBirthday(Date birthday) {
- this.birthday = birthday;
- }
- public String toString() {
- return "User [birthday=" + birthday + ", cha=" + cha + ", gender="
- + gender + ", id=" + id + ", loginname=" + loginname
- + ", score=" + score+ "]";
- }
- }</span></span>
Gender.java
- <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.domain;
- public enum Gender {
- M,F;
- }</span></span>
Tel.java
- <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.domain;
- public class Tel {
- private String areaCode;
- private String phoneCode;
- public String getAreaCode() {
- return areaCode;
- }
- public void setAreaCode(String areaCode) {
- this.areaCode = areaCode;
- }
- public String getPhoneCode() {
- return phoneCode;
- }
- public void setPhoneCode(String phoneCode) {
- this.phoneCode = phoneCode;
- }
- }</span></span>
看看自定义Tel类型的转换器
- <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.converter;
- import java.util.Map;
- import org.apache.struts2.util.StrutsTypeConverter;
- import com.javacrazyer.domain.Tel;
- public class TelConverter extends StrutsTypeConverter {
- //把String转换成Tel类型
- //context:OGNL上下文的Map对象
- //values :需要转换的字符串数组
- //toClass:要转换的目标类型
- @Override
- public Object convertFromString(Map context, String[] values, Class toClass) {
- if(toClass == Tel.class){
- String str = values[0];
- String[] strArr = str.split("-");
- Tel tel = new Tel();
- tel.setAreaCode(strArr[0]);
- tel.setPhoneCode(strArr[1]);
- return tel;
- }
- return null;
- }
- //把Tel类型转换成String类型
- //context:OGNL上下文的Map对象
- //o:需要转换的对象
- @Override
- public String convertToString(Map context, Object o) {
- if(o instanceof Tel){
- Tel tel = (Tel)o;
- return tel.getAreaCode() + "-" + tel.getPhoneCode();
- }
- return null;
- }
- }</span></span>
业务处理UserAction.java
- <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.web.action;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import java.util.Map.Entry;
- import com.javacrazyer.domain.Tel;
- import com.javacrazyer.domain.User;
- import com.opensymphony.xwork2.ActionSupport;
- /**
- * 使用注解来配置Action
- *
- */
- public class UserAction extends ActionSupport {
- private static final long serialVersionUID = -2554018432709689579L;
- private User user;
- private List<String> list;
- private List<User> userList;
- private Set<User> userSet = new HashSet<User>();
- private Map<String, String> map = new HashMap<String, String>();
- private Tel tel;
- public String execute() throws Exception{
- System.out.println(user);
- System.out.println(list);
- for(User user : userList){
- System.out.println(user);
- }
- System.out.println("=========================");
- for(User user : userSet){
- System.out.println(user);
- }
- for (Entry entry:map.entrySet()){
- System.out.println(entry.getKey()+"=="+entry.getValue());
- }
- System.out.println("区号:" + this.tel.getAreaCode());
- System.out.println("电话号:" + this.tel.getPhoneCode());
- return SUCCESS;
- }
- public User getUser() {
- return user;
- }
- public void setUser(User user) {
- this.user = user;
- }
- public List<String> getList() {
- return list;
- }
- public void setList(List<String> list) {
- this.list = list;
- }
- public List<User> getUserList() {
- return userList;
- }
- public void setUserList(List<User> userList) {
- this.userList = userList;
- }
- public Set<User> getUserSet() {
- return userSet;
- }
- public void setUserSet(Set<User> userSet) {
- this.userSet = userSet;
- }
- public Map<String, String> getMap() {
- return map;
- }
- public void setMap(Map<String, String> map) {
- this.map = map;
- }
- public Tel getTel() {
- return tel;
- }
- public void setTel(Tel tel) {
- this.tel = tel;
- }
- }</span></span>
局部类型转换器,与UserAction.java在同一目录
UserAction-conversion.properties
- <span style="font-size: large;"><span style="font-size: large;">tel=com.javacrazyer.converter.TelConverter
- #集合属性-Set类型
- Element_userSet=com.javacrazyer.domain.User
- #指定索引
- KeyProperty_userSet=id
- #指定key类型
- Key_map=java.lang.String
- #指定value类型
- Element_map=java.lang.String</span></span>
全局类型转换器src/xwork-conversion.properties
- <span style="font-size: large;"><span style="font-size: large;">com.qiujy.domain.Tel=com.javacrazyer.converter.TelConverter</span></span>
src/struts.xml
- <span style="font-size: large;"><span style="font-size: large;"><?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
- "http://struts.apache.org/dtds/struts-2.1.7.dtd">
- <struts>
- <!-- 请求参数的编码方式 -->
- <constant name="struts.i18n.encoding" value="UTF-8"/>
- <!-- 指定被struts2处理的请求后缀类型。多个用逗号隔开 -->
- <constant name="struts.action.extension" value="action,do,go,xkk"/>
- <!-- 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开 -->
- <constant name="struts.configuration.xml.reload" value="true"/>
- <!-- 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开 -->
- <constant name="struts.devMode" value="false"/>
- <!-- 设置浏览器是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关闭 -->
- <constant name="struts.serve.static.browserCache" value="false" />
- <!-- 是否允许在OGNL表达式中调用静态方法,默认值为false -->
- <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
- <!-- 指定由spring负责action对象的创建
- <constant name="struts.objectFactory" value="spring" />
- -->
- <!-- 是否开启动态方法调用 -->
- <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
- <package name="my" extends="struts-default" namespace="/">
- <global-results>
- <result name="input">/error.jsp</result>
- </global-results>
- <action name="info" class="com.javacrazyer.web.action.UserAction">
- <result name="success">/info.jsp</result>
- <result name="input">/error.jsp</result>
- </action>
- </package>
- </struts></span></span>
converter.jsp
- <span style="font-size: large;"><span style="font-size: large;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
- <%@ taglib uri="/struts-tags" prefix="s" %>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>Struts2中的转换器</title>
- </head>
- <body>
- <h3>Struts2中的转换器</h3><hr/>
- <form action="info.action" method="post">
- <table>
- <tr>
- <td>登录名</td>
- <td><input type="text" name="user.loginname"/></td>
- </tr>
- <tr>
- <td>生日</td>
- <td><input type="text" name="user.birthday"/></td>
- </tr>
- <tr>
- <td>性别</td>
- <!--OGNL表达式:user属性的gender属性[由于是日期类型,程序中自定义有日期转换器]写法 -->
- <td><input type="radio" name="user.gender" value="M" checked="checked"/>男<input type="radio" name="user.gender" value="F"/>女</td>
- </tr>
- <tr>
- <td>考试成绩</td>
- <td><input type="text" name="user.score"/></td>
- </tr>
- <tr>
- <td colspan="2"><input type="submit" value=" 提交 "/></td>
- </tr>
- </table>
- <!--OGNL表达式:元素类型为String类型的List的写法 -->
- <input type="hidden" name="list[0]" value="张三"/>
- <input type="hidden" name="list[1]" value="李四"/>
- <input type="hidden" name="list[2]" value="王五"/>
- <!--OGNL表达式:元素类型为user类型的LIST属性的写法 -->
- <input type="hidden" name="userList[0].loginname" value="张三"/>
- <input type="hidden" name="userList[1].loginname" value="李"/>
- <input type="hidden" name="userList[2].loginname" value="王"/>
- <!--OGNL表达式:元素类型为user类型的set属性的写法 -->
- <input type="hidden" name="userSet.makeNew[0].loginname" value="xxx"/>
- <input type="hidden" name="userSet.makeNew[1].loginname" value="yyy"/>
- <input type="hidden" name="userSet.makeNew[2].loginname" value="ggg"/>
- <!--OGNL表达式:map属性的写法 -->
- <input type="hidden" name="map['jolin']" value="caiyilin"/>
- <input type="hidden" name="map['jay']" value="zhoujielun"/>
- <!--OGNL表达式:Tel属性的写法 -->
- <input type="hidden" name="tel" value="010-66298878"/>
- </form>
- </body>
- </html></span></span>
info.jsp
- <span style="font-size: large;"><span style="font-size: large;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
- <%@ taglib uri="/struts-tags" prefix="s" %>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>显示提交的数据</title>
- </head>
- <body>
- <h3>显示提交的数据</h3><hr/>
- <table>
- <tr>
- <td>登录名</td>
- <td><s:property value="user.loginname"/> </td>
- </tr>
- <tr>
- <td>生日</td>
- <td><s:date name="user.birthday" format="yyyy-MM-dd HH:mm:ss"/></td>
- </tr>
- <tr>
- <td>性别</td>
- <td><s:property value="user.gender"/> </td>
- </tr>
- <tr>
- <td>考试成绩</td>
- <td><s:property value="user.score"/></td>
- </tr>
- <tr>
- <td>电话号</td>
- <td><s:property value="tel"/></td>
- </tr>
- <tr>
- <td colspan="2"><input type="button" value=" 返回 " onclick="history.go(-1);" /></td>
- </tr>
- </table>
- <hr/><s:debug/>
- </body>
- </html></span></span>
error.jsp
- <span style="font-size: large;"><span style="font-size: large;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
- <%@ taglib uri="/struts-tags" prefix="s" %>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>出现内部错误</title>
- </head>
- <body>
- <h3>出现内部错误</h3><hr/>
- <s:actionerror/>
- </body>
- </html></span></span>
总结
Struts2中的类型转换器
1) Struts2中内置了一些常用的类型转换器:可以把客户端提交的String数据转换成对应类型的数据。
a) 基本类型
b) java.util.Date:
c) 数组和列表
2) 自定义类型转换器:
a) 继承自org.apache.struts2.util.StrutsTypeConverter类
public abstract Object convertFromString(Map context, String[] values, Class toClass);
context:OGNL上下文的Map对象
values :需要转换的字符串数组
toClass:要转换的目标类型
public abstract String convertToString(Map context, Object o);
context:OGNL上下文的Map对象
o:需要转换的对象
b) 注册:以全局方式
在应用程序的classpath下创建一属性文件,名为:xwork-conversion.properties
文件内容:待转换类型的全限定名=类型转换器类的全限定名
3) 转换Set:
0) Action中的Set属性需要进行初始化:如:
private Set<User> userSet = new HashSet<User>();
a) 添加针对某个Action的转换器配置文件:ActionName-conversion.properties 如:
UserAction-conversion.properties
b) 在这个文件中添加:Action的Set属性的相关配置
Element_属性名=Set中的元素类型的全限定名 #指定Set中的元素类型
KeyProperty_属性名=Set中的元素类型中的某个属性 #指定Set的索引字段
如下示例:
Element_userSet=com.qiujy.domain.User
KeyProperty_userSet=id
c) JSP页面: <input type="text" name="Set属性名.makeNew[0].属性名"/>
如:<input type="text" name="userSet.makeNew[0].loginname"/>
- (七)struts2之自定义类型转换器
- Struts2之自定义类型转换器
- Struts2之自定义类型转换器
- Struts2之自定义类型转换器
- Struts2之自定义类型转换器
- Struts2之自定义类型转换器
- Struts2之自定义类型转换器
- Struts2之自定义类型转换器
- Struts2之自定义类型转换器
- Struts2之自定义类型转换器
- Struts2之自定义类型转换器
- Struts2之自定义局部类型转换器、全局类型转换器
- 复习struts2之自定义类型转换器
- Struts2学习笔记之自定义类型转换器
- Struts2学习笔记之自定义类型转换器
- Struts2自定义类型转换器
- struts2 自定义类型转换器
- struts2自定义类型转换器
- mangos分析
- input输入子系统源码部分函数分析
- 重签名apk
- 取模和求余的区别
- 数据库高可用性——SQL Server 2005数据库复制简单图解
- (七)struts2之自定义类型转换器
- VC用一组Bitmap创建TIFF格式的图片
- .NET学习最应该知道的知识点
- delphi 里的二分法查找
- sqlserver 触发器
- 宏BUF_SIZE_BYTES(buf)和BUF_SIZE_CHARS(buf)计算数组最大容纳字节数和字符数
- 用RAW模式查询创建XML(SQL Server 与 XML 笔记)
- Android SDK Simple 例程分析之 ApiDemos 的 ApiDemos.java 分析
- 文件系统,草记