struts2类型转换

1.先给一个PointBean,要求对这个bean进行类型转换

  1. public class Point {
  2.     private int x;
  3.     private int y;
  4.     public int getX() {
  5.         return x;
  6.     }
  7.     public void setX(int x) {
  8.         this.x = x;
  9.     }
  10.     public int getY() {
  11.         return y;
  12.     }
  13.     public void setY(int y) {
  14.         this.y = y;
  15.     }
  16. }

2.两种转换器, 第一个侧重于告诉大家转换原理, 第二个侧重具体实践

  1. package edu.hust.common;
  2. import java.util.Map;
  3. import ognl.DefaultTypeConverter;
  4. import edu.hust.bean.Point;
  5. //较为底层的一个转换方法,一般项目中不直接继承DefaultTypeConverter实现转换,因为还有StrutsTypeConverter(继承自DefaultTypeConverter)进行了更好的封装。使我们更方便使用。
  6. //这里的例子为了大家理解这个机制。
  7. public class Converter extends DefaultTypeConverter {
  8.     @SuppressWarnings("unchecked")
  9.     @Override
  10.     public Object convertValue(Map context, Object value, Class toType) {
  11.         /*
  12.          * toType: 当客户端提交数据时,要求String类型转换为自定义类型进行业务处理or存储(eg:String转为Point类);
  13.          * 当客户端接收数据时,要求自定义类型转换为String类型进行显示输出。
  14.          * toType起到了类型判断的作用。
  15.          */
  16.         //String转换为Point(Point为被转换(toType)类型, 也即目标类型)
  17.         if (Point.class == toType) {
  18.             Point point = new Point();
  19.             
  20.             //String[] paramValues = ((String)value).split(",");建议这一句用下面两句去替代。
  21.             /*
  22.              * 为什么要将value转换为String[]呢?
  23.              * 我们在做表单时可以给2个or多个text的name属性赋予相同的值(即相同名字)。这样的话,server端接收name属性对应的表单属性时,接收过来的是一个数组(eg: 在Servlet中是用req.getParameterValues()接收这个数组的)。
  24.              * 方法接口为:public String[] getParameterValues(String name);
  25.              */
  26.             String[] strTxt = (String[]) value;
  27.             String[] paramValues = strTxt[0].split(",");
  28.             
  29.             
  30.             int x = Integer.parseInt(paramValues[0]);
  31.             int y = Integer.parseInt(paramValues[1]);
  32.             
  33.             point.setX(x);
  34.             point.setY(y);
  35.             
  36.             return point;
  37.         }
  38.         //String为目标类型(当然不转换toString()方法会被调用,但我们不希望这样)
  39.         if (String.class == toType) {
  40.             Point point = (Point)value;
  41.             int x = point.getX();
  42.             int y = point.getY();
  43.             String result = x + "," + y;
  44.             return result;
  45.         }
  46.         return null;
  47.     }
  48. }
  1. package edu.hust.common;
  2. import java.util.Map;
  3. import org.apache.struts2.util.StrutsTypeConverter;
  4. import edu.hust.bean.Point;
  5. public class Converter2 extends StrutsTypeConverter {
  6.     @SuppressWarnings("unchecked")
  7.     @Override
  8.     public Object convertFromString(Map context, String[] values, Class toClass) {
  9.         Point point = new Point();
  10.         
  11.         String[] paramValues = values[0].split(",");
  12.         
  13.         
  14.         int x = Integer.parseInt(paramValues[0]);
  15.         int y = Integer.parseInt(paramValues[1]);
  16.         
  17.         point.setX(x);
  18.         point.setY(y);
  19.         
  20.         return point;
  21.     }
  22.     @SuppressWarnings("unchecked")
  23.     @Override
  24.     public String convertToString(Map context, Object o) {
  25.         Point point = (Point)o;
  26.         int x = point.getX();
  27.         int y = point.getY();
  28.         String result = "[x坐标:" + x + "],[y坐标:" + y +"]";
  29.         return result;
  30.     }
  31. }

3.action:请详细阅读下面这个action的中的注释

  1. package edu.hust.action;
  2. import java.util.Date;
  3. import com.opensymphony.xwork2.ActionSupport;
  4. import edu.hust.bean.Point;
  5. public class ConverterAction extends ActionSupport {
  6.     
  7.     /*
  8.      * 如何让ConvertorAction知道Convertor类,并调用其中convertValue()方法进行类型转换呢?: 需要在ConvertorAction类所在的保内建立一个资源文件:ConvertorAction-conversion.properties.
  9.      * 
  10.      * 在这个类中进行setter,getter方法时,ConvertorAction类会自动检测所在包内有没有(属性类型转换的)资源文件存在。如果存在则优先执行*.properties文件。
  11.      * 在*.properties文件中调用edu.hust.common.Convertor类进行类型转换后,再执行setter,getter方法。
  12.      * 
  13.      * 对于int,Date类型,struts2自动进行转化。不必我们去写转化代码。但如果我们也手工写了转化代码,则优先使用我们的转化代码。如果我们没有定义转化,struts2自动转化。
  14.      * 对于自动转换的类型,struts2也会进行输入校验。对于int,Date类型的,如果我们输入字符串去提交,struts2自动校验并根据反射技术,把错误打印到对应输入表单之上(这里就必须使用struts2的表单,不能使用el进行输出)。
  15.      * 在这里我们不推荐使用struts2的自动验证,其一其功能有限,其二其错误输出信息只是给程序员看的,而会让使用者一头雾水。
  16.      * 解决方法:找到自动提示的错误信息,将错误信息内容覆盖为我们希望看到的--通过资源文件。
  17.      * 
  18.      * 注:在result页面显示的时候,注意用<s:property>标签显示和用el显示的区别(区别很大)。
  19.      *
  20.      * */
  21.     
  22.     private static final long serialVersionUID = 1L;
  23.     
  24.     private Point point;
  25.     private int age;
  26.     private String username;
  27.     private Date date;
  28.     public Point getPoint() {
  29.         return point;
  30.     }
  31.     public void setPoint(Point point) {
  32.         this.point = point;
  33.     }
  34.     public int getAge() {
  35.         return age;
  36.     }
  37.     public void setAge(int age) {
  38.         this.age = age;
  39.     }
  40.     public String getUsername() {
  41.         return username;
  42.     }
  43.     public void setUsername(String username) {
  44.         this.username = username;
  45.     }
  46.     public Date getDate() {
  47.         return date;
  48.     }
  49.     public void setDate(Date date) {
  50.         this.date = date;
  51.     }
  52.     @Override
  53.     public String execute() throws Exception {
  54.         return SUCCESS;
  55.     }
  56.     
  57. }

4.类型转换的局部资源配置文件ConverterAction-conversion.properties

  1. # 局部的 --> 类型转换资源文件
  2. # 这个资源文件的文件名是有规定的: 
  3. # 前半部分:ConvertorAction --> 必须与对应的Action一致。
  4. # 后半部分:-conversion.properties --> 固定格式,不能修改。
  5. # 书写内容:你对ConvertorAction中的哪个属性进行转换
  6. # 对ConvertorAction类中的point对象属性,用edu.hust.common.Convertor类进行转换
  7. # 局部convertion.properties和全局convertion.properties同时定义了对某一类型的转换时,局部有效、全局无效。
  8. point = edu.hust.common.Converter

类型转换的全局资源配置文件xwork-conversion.properties

  1. # 全局的 --> 类型转换资源文件
  2. # 这个资源文件的文件名是固定的,不能修改。 
  3. # 对整个的PointBean进行转换,无论哪里用到Point类(即只要调用了PointBean),转换就会执行。
  4. # 局部convertion.properties和全局convertion.properties同时定义了对某一类型的转换时,局部有效、全局无效。
  5. edu.hust.bean.Point = edu.hust.common.Converter2

5.最后是struts.xml和jsp页面, 这些和普通struts2无异

  1. <%@ page contentType="text/html;charset=GBK"%>
  2. <%@ taglib prefix="s" uri="/struts-tags" %>
  3. <s:form action="converter" method="post">
  4.     <s:textfield name="point" label="point" />
  5.     <s:textfield name="age" label="age" />
  6.     <s:textfield name="username" label="username" />
  7.     <s:textfield name="date" label="date" />
  8.     <s:submit label="submit" />
  9. </s:form>
  1. <!DOCTYPE struts PUBLIC
  2.           "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
  3.           "http://struts.apache.org/dtds/struts-2.0.dtd">
  4. <struts>
  5.     <package name="struts2" extends="struts-default">
  6.         <action name="converter" class="edu.hust.action.ConverterAction">
  7.             <result>/result.jsp</result>
  8.         </action>
  9.     </package>
  10. </struts>
  1. <%@ page contentType="text/html;charset=GBK"%>
  2. <%@ taglib prefix="s" uri="/struts-tags" %>
  3. <html>
  4.     <head><title>Login Page</title></head>
  5.     <body bgcolor="#99ffff">
  6.         <!-- 如果使用了*.properties进行类型转化,你会发现用el输出和用s标签输出效果完全不同, 建议使用s标签 -->
  7.         
  8.         <h2>使用s标签显示</h2>
  9.         point: <s:property value="point" /><br>
  10.         age: <s:property value="age" /><br>
  11.         username: <s:property value="username" /><br>
  12.         date: <s:property value="date" /><br><br>
  13.         
  14.         <h2>使用el显示</h2>
  15.         point: ${point}<br>
  16.         age: ${age}<br>
  17.         username: ${username}<br>
  18.         date: ${date}<br>
  19.     </body>
  20. </html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值