使用DefaultTypeConverter
---------------------------
web页面往后台传值,只能传递字符串,要使得字符串能自动的转换成一个类,以便于后台能更好的处理数据,就需要使用到struts中的类型转换器了。
比如,页面上传递一个值"zhangsan,20",表示张三,20岁,action中可以直接获得直接获得这样一个user对象。即在action中能使用如下的代码:
- public class testconvert extends ActionSupport
- {
- private User user333;
- @Override
- public String execute() throws Exception
- {
- System.out.println("username: " + user333.getUsername());
- System.out.println("age: " + user333.getAge());
- return SUCCESS;
- }
- }
定义了user类型,并且在execute方法中可以直接使用user这个对象。
要实现这个功能,就需要把传过来的string转变成user对象。
转换的方式需要一个转换类,并且这个转换类必须继承DefaultTypeConverter类,然后,实现它的convertValue方法。
实现了转换类之后,还需要一个配置文件,来指示说明该转换类用于转换哪个变量的,(java真的很繁琐)。
首先要覆盖掉DefaultTypeConverter类中的convertValue方法,该方法有3个重载,通常覆盖签名如下的方法:
public Object convertValue(Map context, Object value, Class toType)
其中Map context没有什么用。
常规写法如下:
- public class UserConverter extends DefaultTypeConverter {
- @Override
- public Object convertValue(Map context, Object value, Class toType) {
- System.out.println("convertValue");
- if(myUser.class == toType) //从页面向后台对象转换
- {
- //value是一个数组,因为它是根据表单中可能有多个元素的name属性是相同的,因此只要name属性为指定的表单元素的值都会被传输过来。
- String[] str = (String[])value;
- //通常只会取第一个。
- String firstValue = str[0];
- System.out.println(firstValue);
- StringTokenizer st = new StringTokenizer(firstValue, ",");
- String username = st.nextToken();
- int age =Integer.parseInt( st.nextToken());
- myUser user = new myUser();
- user.setUsername(username);
- user.setAge(age);
- return user;
- }
- else if(String.class == toType) //从后台对象向页面转换
- {
- myUser user = (myUser)value;
- String username = user.getUsername();
- int age = user.getAge();
- String userInfo = "username: " + username + ", age: " + age;
- return userInfo;
- }
- return null;
- }
- }
然后在action类中,把要转换的对象,完成他们的set和get方法,注意大小写,set,get后的字母要大写,这是基于约定的。OGNL转换会去找这2个方法调用的。
- public class testconvert extends ActionSupport
- {
- private myUser user333;
- public myUser getUser333() {
- System.out.println("getuser333");
- return user333;
- }
- public void setUser333(myUser user) {
- System.out.println("setuser333");
- this.user333 = user;
- }
- @Override
- public String execute() throws Exception
- {
- System.out.println("username: " + user333.getUsername());
- System.out.println("age: " + user333.getAge());
- System.out.println("execute");
- return SUCCESS;
- }
- }
接下来属性文件的命名,必须是按照固定格式的,action类名-conversion.properties,此例中命名为testconvert-conversion.properties,和action类在同一级目录下。如果要寻找某一个action中的某属性对应的转换类,必须按照这种文件名格式寻找对应的文件。属性文件中如下编码格式为:
属性名=转换类,此例中为:
user333=com.tutorialspoint.sconvert.UserConverter,表示user333这个值用com.tutorialspoint.sconvert.UserConverter这个类做转换。
注意,此处的键名user333,是根据setUser333,getUser333而命名的,并不是根据private myUser user333,因此,即使把private的user333改成变量user444,只要set和get的名字不改,properties文件中依旧是用user333作为键名。
在jsp提交页面中,编码如下:
- <form action=testconvert method="post">
- Please enter your name<br/>
- <input type="text" name="user333"/>
- <input type="submit" value="test"/>
- </form>
此处的变量名都要对应相同,不然会出错。
对于从Javabean中把值传到前台的HTML,上面的编码已经展示了,唯一要做的是在展示页面把该值读出来。
通过语句<s:property value="user333"/>即可,该语句会调用getUser333这个方法,进而调用 UserConverter 中的convertValue方法,完成转换。
使用StrutsTypeConverter
--------------------------------
由于继承DefaultTypeConverter需要做类型判断等操作,比较麻烦,strut2提供了StrutsTypeConverter,该类一个抽象类,是对DefaultTypeConverter的继承。该类是把之前convertValue方法中的if判断逻辑,封装成2个不同的方法。分别是convertFromString(Map context, String[] values, Class toClass) 和 convertToString(Map context, Object o)
这样的话,逻辑上更为清晰。如可以参照之前的UserConverter类,实现UserConverter2类。完成一样的工作。
- public class UserConverter2 extends StrutsTypeConverter {
- @Override
- public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
- System.out.println("convertFromString");
- //通常只会取第一个。
- String firstValue = arg1[0];
- System.out.println(firstValue);
- StringTokenizer st = new StringTokenizer(firstValue, ",");
- String username = st.nextToken();
- int age =Integer.parseInt( st.nextToken());
- myUser user = new myUser();
- user.setUsername(username);
- user.setAge(age);
- return user;
- }
- @Override
- public String convertToString(Map arg0, Object arg1) {
- System.out.println("convertToString");
- myUser user = (myUser)arg1;
- String username = user.getUsername();
- int age = user.getAge();
- String userInfo = "username: " + username + ", age: " + age;
- return userInfo;
- }
- }
当然,运行前要记得在properties文件中,将
user333=com.tutorialspoint.sconvert.UserConverter改成
user333=com.tutorialspoint.sconvert.UserConverter2
全局转换器
----------------------------------
对于某些类型,需要在全局实现转换,则对单个action配置properties文件比较繁琐,struts提供了全局转换配置文件,只需在src目录下新建xwork-conversion.properties文件即可,在文件中依旧是键值对,
但是键名有变化,为具体的类型=对应类型转换器。此例中,内容即写为:
com.tutorialspoint.struts2.myUser=com.tutorialspoint.sconvert.UserConverter2,而实现转换逻辑的类依旧不变。
附件:http://down.51cto.com/data/2362490
本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/1163288,如需转载请自行联系原作者