zoukankan      html  css  js  c++  java
  • Struts2之类型转换器

    一、类型转换器的应用场景

    类型转换是OGNL的一部分,默认的八种基本类型、String、Date会使用类型转换,但是更复杂的类型转换就需要我们自定义了(虽然这个东西一般根本用不到),OGNL可以应用在很多领域,但是在web领域,因为在客户端到服务器端传输的只是字符串,所以这里就有一个需求收缩,我们的需求就变为完成String和复杂对象之间的互相转换
    在Struts2中的类型转换则是在客户端的请求参数往Action的成员属性中设置的时候会被调用。

    二、如何使用?

    1.理论部分

    所有的类型转换器都要实现TypeConverter接口,Struts2有需求收缩,只满足 String<-->复杂对象 就可以了,所以它提供了一个抽象类叫做StrutsTypeConverter,我们自定义的类型转换器只要继承这个类然后实现它的两个抽象接口就可以了。
    我们写完了这个类型转换器的代码,但是怎么才能让Struts2知道去使用它呢?这里分为了两种情况:

    Action级别
    在Action的同级别目录下放置“ActionName-conversion.properties”,在此文件使用“propertyName=typeConverterClassName”的格式为属性指定类型转换器。
    比如:
    文件名:PointAction-conversion.properties
    内容:point=struts_practice_005.PointTypeConverter

    全局级别
    在类路径下放置“xwork-conversion.properties”,在此文件中使用“ObjectName=typeConverterClassName”的格式为对象指定类型转换器。
    比如:
    文件名:xwork-conversion.properties
    内容:struts_practice_006.Circle=struts_practice_006.CircleTypeConverter

    总结一下:
    定义一个类型转换器分为两步:
    1.继承StrutsTypeConverter,实现它的两个抽象方法。
    2.写properties文件告诉Struts2应该如何使用。

    2.实践部分

    两个例子(Action级别类型转换器 & 全局级别类型转换器):

    2.1 一个字符串到Point对象的转换。(使用Action级别)
    结构如下:

    image

    Point:

    /**
     * 表示一个点
     * @author CC11001100
     * 
     */
    public class Point {
    
        private double x;
        private double y;
    
        public Point() {
        }
        
        public Point(double x, double y) {
            super();
            this.x = x;
            this.y = y;
        }
    
        @Override
        public String toString() {
            //toString--> (x,y)
            return "("+x+","+y+")";
        }
    
        public double getX() {
            return x;
        }
    
        public void setX(double x) {
            this.x = x;
        }
    
        public double getY() {
            return y;
        }
    
        public void setY(double y) {
            this.y = y;
        }
    
    }
    Action:
    import com.opensymphony.xwork2.ActionSupport;
    
    public class PointAction extends ActionSupport {
    
        private Point point;
    
        @Override
        public String execute() throws Exception {
            
            System.out.println(point);
            
            return super.execute();
        }
    
        public Point getPoint() {
            return point;
        }
    
        public void setPoint(Point point) {
            this.point = point;
        }
    
    }
    类型转换器PointTypeConverter :
    import java.util.Map;
    
    import org.apache.struts2.util.StrutsTypeConverter;
    
    /**
     * 完成 Point对象<-->String 的互相转换
     * 
     * @author CC11001100
     * 
     */
    public class PointTypeConverter extends StrutsTypeConverter {
    
        /**
         * 这个方法完成从String-->Point的类型转换
         */
        @Override
        public Object convertFromString(Map context, String[] values, Class toClass) {
            if (values.length > 0) {
                String s = values[0];
                String ss[] = s.split(",");
                if (ss.length != 2)
                    return null;
                double x = Double.parseDouble(ss[0].substring(1, ss[0].length()));
                double y = Double
                        .parseDouble(ss[1].substring(0, ss[1].length() - 1));
                return new Point(x, y);
            } else {
                return null;
            }
        }
    
        /**
         * 这个方法完成从Point-->String的转换
         */
        @Override
        public String convertToString(Map context, Object o) {
            // 偷个懒,直接调用toString()
            if (o != null)
                return o.toString();
            return null;
        }
    
    }

    配置PointAction-conversion.properties(Action级别):

    point=struts_practice_005.PointTypeConverter

    struts.xml:

    <struts>
        <package name="default" namespace="/" extends="struts-default">
            <action name="pointAction" class="struts_practice_005.PointAction">
                <result >/result.jsp</result>
            </action>
        </package>
    </struts>

    前端页面:

    <form action="pointAction" method="post">
          <input type="text" name="point" />
          <input type="submit" value="提交" />
      </form>

    结果当然是转换成功啦,可以看到控制台的打印结果:
    image
    前端页面的显示结果:
    image
    当客户端发来的请求参数point=(1,2)发送到服务器的时候,它设置之前会看一下是否给这个对象设置了类型转换器,如果设置了就交给类型转换器就可以了,所以这里是调用了PointTypeConverter的convertFromString()方法。

    2.2 一个字符串到Circle对象的转换。(使用全局级别)

    概览:

    image

    Circle:

    /**
     * 表示一个圆
     * 
     * @author CC11001100
     * 
     */
    public class Circle {
    
        // 圆的半径
        private double r;
    
        public Circle() {
        }
    
        public Circle(double r) {
            super();
            this.r = r;
        }
    
        @Override
        public String toString() {
            // toString() --> "C:rxx"
            return "C:r" + r;
        }
    
        public double getR() {
            return r;
        }
    
        public void setR(double r) {
            this.r = r;
        }
    
    }

    CircleAction:

    import com.opensymphony.xwork2.ActionSupport;
    
    public class CircleAction extends ActionSupport {
    
        private Circle circle;
    
        @Override
        public String execute() throws Exception {
    
            return SUCCESS;
        }
    
        public Circle getCircle() {
            return circle;
        }
    
        public void setCircle(Circle circle) {
            this.circle = circle;
        }
    
    }

    CircleTypeConverter:

    /**
     * 完成从 String<-->Circle 的互相转换.
     * @author CC11001100
     *
     */
    public class CircleTypeConverter extends StrutsTypeConverter {
    
        @Override
        public Object convertFromString(Map context, String[] values, Class toClass) {
            if (values.length > 0) {
                String s = values[0];
                if(s.indexOf("C:r")==-1) return null;
                s=s.substring(3,s.length());
                double r=Double.parseDouble(s);
                return new Circle(r);
            } else {
                return null;
            }
        }
    
        @Override
        public String convertToString(Map context, Object o) {
            if(o!=null) return o.toString();
            return null;
        }
    
    }

    struts.xml

    <struts>
        <package name="default" namespace="/" extends="struts-default">
            <action name="circleAction" class="struts_practice_006.CircleAction">
                <result >/result.jsp</result>
            </action>
        </package>
    </struts>

    xwork-conversion.properties:

    struts_practice_006.Circle=struts_practice_006.CircleTypeConverter

    前端:

    <form action="circleAction" method="post">
        <input type="text" name="circle" /> 
        <input type="submit" value="提交" />
    </form>

    result.jsp:

    <s:property value="circle" />
      <s:debug />

    输入:

    image

    输出:

    image

    <s:property value="circle" /> 得到的值使用了类型转换器,<s:debug />显示的ValueStack中的值没有使用类型转换器,证明:
    给类型转换器的convertToString加点料。如下:

    public class CircleTypeConverter extends StrutsTypeConverter {
    
        ...
        
        @Override
        public String convertToString(Map context, Object o) {
            if(o!=null) return o.toString()+"类型转换器";
            return null;
        }
    
    }

    如图:

    image
    三、工作原理?

     

    待更、

  • 相关阅读:
    基于flash的web视频对讲直播测试
    终于放弃Windows下丑陋的cmd
    直播推流兼容性问题追踪
    32位和64位dll判断
    H264编码参数的一些小细节
    cmake编译win下64位obs
    The certificate used to sign "XXX" has either expired or has been revoked
    记录一次Android交叉编译ffmpeg排查错误
    SDK "iphoneos" cannot be located
    av_interleaved_write_frame 网络不好的情况下返回较慢
  • 原文地址:https://www.cnblogs.com/cc11001100/p/5937199.html
Copyright © 2011-2022 走看看