zoukankan      html  css  js  c++  java
  • Struts2实现类型转换器(十五)

    勿以恶小而为之,勿以善小而不为--------------------------刘备
    劝诸君,多行善事积福报,莫作恶

    上一章简单介绍了Struts2实现JSON和Ajax操作(十四),如果没有看过,请观看上一章

    一. Struts2的类型转换器

    一. 一 类型转换器出现的原因

    在Servlet+JSP的开发过程中,我们常常需要手动的去转换传入的值的类型,

    因为前端form表单里,所有传入的类型都会被默认成String 或者是String [] 。

    所以,即使是 年龄 age 这样的int 字段传入时,也同样先需要进行类型转换:

    String ageForm=request.getParameter("age");
    
    int age=Integer.parseInt(ageForm);
    
    

    对于每一个传入的参数,除了 String 和 String[] 数组外,都需要进行类型转换,如常见的 int,double,Date 等类型, 还有一些我们自定义的类型转换。 这样的操作,是枯噪的。 所以 Struts2 框架封装了一些常见的类型转换,来简化参数的接收。

    这些类型封装器,在 com.opensymphony.xwork2.conversion.impl 包下面。

    一.二. Struts2提供的 内置的类型转换器

    引用于: https://blog.csdn.net/qq_20453707/article/details/50825497


    在这里插入图片描述


    包括基本类型的转换,Date,数组和集合的转换。 Struts2可以通过类型转换器,基本上可以满足常见的一些需求。

    其对应的类型转换器实现为:

    有图片

    然而,这些在实际大型项目开发中,是不够的, 用户需要自己定义类型转换器。

    可以通过 实现 DefaultTypeConverter 和 StrutsTypeConverter 进行实现 自定义类型转换。

    二. 自定义类型转换 DefaultTypeConverter

    二.一 所用到的接口 API

    二.一.一 TypeConverter 接口

    类型转换的时候,用的是 TypeConverter 接口.

    是xwork下的接口。

    在 com.opensymphony.xwork2.conversion.TypeConverter包下

     public abstract interface TypeConverter
    {
     public static final Object NO_CONVERSION_POSSIBLE = "ognl.NoConversionPossible";
      public static final String TYPE_CONVERTER_CONTEXT_KEY = "_typeConverter";
      public abstract Object convertValue(Map<String, Object> paramMap,
       Object paramObject1, Member paramMember, String paramString, Object paramObject2, Class paramClass);
    }
    

    二.一.二 DefaultTypeConverter 默认类型转换接口

    DefaultTypeConverter

    里面定义了基本的类型转换。

    public class DefaultTypeConverter
     implements com.opensymphony.xwork2.conversion.TypeConverter{
    
    	...
    	//方法里面,通过判断参数的类型,进行不同的处理 
    	...
     	
     }
    

    二.二 实现Date 类型的转换

    Struts2提供的 Date 类型转换器, com.opensymphony.xwork2.conversion.impl.DateConverter,需要符合一定的格式, Short 格式, 一般不使用默认的Date 类型转换。

    二.二.一 创建 MyAction1 控制器

    package com.yjl.web.action;
    
    import java.util.Date;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    /**
    @Date: 2019年3月27日
    @author: 两个蝴蝶飞
    @Description: 简单的类型转换
    */
    public class MyAction1 extends ActionSupport{
    	private static final long serialVersionUID = 1L;
    	private Date birthday;
    	@Override
    	public String execute() throws Exception {
    		 //这个是对象
    		System.out.println("输出生日为:"+birthday.getYear());
    		return NONE;
    	}
    	public Date getBirthday() {
    		return birthday;
    	}
    	public void setBirthday(Date birthday) {
    		this.birthday = birthday;
    	}
    }
    

    二.二.二 配置struts.xml文件

    <struts>
    	<package name="typeConverter" extends="struts-default" namespace="/">
    		
    		<action name="MyAction1" class="com.yjl.web.action.MyAction1">
    			
    		</action>
    		<!-- 配置跳转页面 -->
    		<action name="*">
    			<result>/WEB-INF/content/{1}.jsp</result>
    		</action>
    	</package>
    </struts>
    

    二.二.三 自定义Date类型转换器 DateTypeConversion

    package com.yjl.conversion;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Map;
    
    import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
    
    /**
    @Date: 2019年3月25日
    @author:两个蝴蝶飞
    @Description:日期的类型转换器
    */
    public class DateTypeConversion extends DefaultTypeConverter{
    	//传递进来的value是数组。
    	@SuppressWarnings("rawtypes")
    	@Override
    	public Object convertValue(Map<String, Object> context, Object value,  Class toType) {
    		// 判断要转换的类型 toType 是Date 类型 
    		if(toType==java.util.Date.class){  
    			//需要手动判断值,要转换成日期类型
    			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    			try {
    				// value 接收的是字符串数组,前台传入的都是字符串类型的。用数组进行接收。
    				String [] values=(String [])value;
    				System.out.println("值是:"+values[0]);
    				return sdf.parse(values[0]);
    			} catch (ParseException e) {
    				e.printStackTrace();
    			}
    		}else if(toType==String.class){
    			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    			System.out.println("转换成字符串");
    			return sdf.format((Date)value);
    		}else {
    			System.out.println("没有办法进行转换");
    		}
    		return null;
    	}
    }
    

    二.二.四 配置 类型转换器的级别

    自定义的类型转换器可以分成两种,一种是Action级别的,一种是全局级别的。

    如果是Action级别的话,

    1. 文件名称必须是: Action的名称-conversion-properties
    2. 必须要与Action在同一目录下
    3. 内容是: Action中的属性=要转换的自定义类型转换器的全限定名称

    如果是全局级别的话:

    1. 文件名称 必须是 xwork-conversion.properites
    2. 必须放置在 src 目录,即classpath 目录下
    3. 内容是: 自定义的类全限定名称=要转换的类型转换器的全限定名称

    故: 对于DateTypeConversion 类型转换器来说, 其对应的级别配置文件为:

    MyAction1-conversion.properties, 需要放置在 com.yjl.web.action 包下.

    内容是:

    
    ##Action属性=全限定名称
    birthday=com.yjl.conversion.DateTypeConversion
    
    

    二.二.五 编写前端界面 /content/mydate.jsp

    <s:form action="MyAction1" method="post" namespace="/">
    		生日:<input type="text" name="birthday">
    		<s:submit value="提交" />
    </s:form>
    

    二.二.六 验证

    启动服务器,进行相关的验证

    输入网址: http://localhost:8080/Struts_Converter/mydate

    有图片

    控制台打印输出:

    有图片

    可以正确地进行转换对象。

    其实,当输入 yyyy-MM-dd 形式时, Struts2提供的默认的类型转换器 DateConverter 也可以进行转换。

    如何区分,用的是默认的,还是用的我们自定义的呢? 就在 System.out.println() 打印的那句话。

    那句话,打印了,我们就实现了自定义的, 那句话,没有打印,那么我们用的就是Struts2定义的,此时就要看一下,是否配置错误了。

    输入可以转换,那么输出是否可以转换呢?

    二.二.七 验证一下,输出转换成字符串,是否进行了转换

    二.二.七.一 对Action 进行转换一下

    @Override
    public String execute() throws Exception {
    	 //这个是对象
    	System.out.println("输出生日为:"+birthday.getYear());
    	return SUCCESS;
    }
    

    让其返回到一个界面,进行显示数据。

    二.二.七.二 配置 struts.xml 文件

    <action name="MyAction1" class="com.yjl.web.action.MyAction1">
    			<result>/WEB-INF/content/show.jsp</result>
    </action>
    

    二.二.七.三 类型转换器和配置文件 MyAction1-conversion.property 保持不变

    二.二.七.四 编写 /content/show.jsp 页面

    <body>
    <s:property value="birthday"/>
    </body>
    

    二.二.七.五 重启服务器,进行验证

    输入网址: http://localhost:8080/Struts_Converter/mydate

    日期填写 1949-10-01 号,祖国母亲的生日

    有图片

    点击按钮,控制台打印输出:

    有图片

    页面跳转显示:

    有图片

    说明,Date 对象 转换成字符串 也是成功的。

    然而,这种方式,还需要自己进行类型判断,不太好,所以在实际的开发中,常常使用的是StrutsTypeConverter

    三. StrutsTypeConverter 实现类型转换

    三.一 StrutsTypeConverter 类定义

    public abstract class StrutsTypeConverter
      extends DefaultTypeConverter{
        //有两个抽像的方法,需要重写
        //转换成对象
      	public abstract Object convertFromString(Map paramMap, String[] paramArrayOfString, Class paramClass);
      	//转换成字符串
     	public abstract String convertToString(Map paramMap, Object paramObject);
      }
    

    我们用 坐标转换这个功能 吧。

    三.二 坐标转换功能展示 StrutsTypeConverter 类型转换

    三.二.一 自定义 Point 类

    package com.yjl.pojo;
    /**
    @Date: 2019年3月27日
    @author: 两个蝴蝶飞
    @Description:Struts类型转换器的自定义类
    */
    public class Point {
    	/**
    	 * @param x 经坐标
    	 * @param y 纬坐标
    	 */
    	private float x;
    	private float y;
    	public float getX() {
    		return x;
    	}
    	public void setX(float x) {
    		this.x = x;
    	}
    	public float getY() {
    		return y;
    	}
    	public void setY(float y) {
    		this.y = y;
    	}
    	@Override
    	public String toString() {
    		return "Point [x=" + x + ", y=" + y + "]";
    	}
    }
    

    三.二.二 编写控制器 MyAction2

    package com.yjl.web.action;
    
    import com.opensymphony.xwork2.ActionSupport;
    import com.yjl.pojo.Point;
    
    /**
    @Date: 2019年3月25日
    @author: yuejl
    @Description:自定义类型转换
    */
    public class MyAction2 extends ActionSupport{
    	private static final long serialVersionUID = 1L;
    	private Point point;
    	@Override
    	public String execute() throws Exception {
    		System.out.println("输出点:"+point.toString()); //这个是对象
    		return SUCCESS;
    	}
    	public Point getPoint() {
    		return point;
    	}
    	public void setPoint(Point point) {
    		this.point = point;
    	}
    }
    
    

    三.二.三 配置struts.xml

    <action name="MyAction2" class="com.yjl.action.MyAction2">
    			<result>/WEB-INF/content/show2.jsp</result>
    </action>
    

    三.二.四 编写类型转换器 PointTypeConverter

    package com.yjl.conversion;
    
    import java.util.Map;
    
    import org.apache.struts2.util.StrutsTypeConverter;
    
    import com.yjl.pojo.Point;
    
    /**
    @Date: 2019年3月27日
    @author: yuejl
    @Description:Point类型转换
    */
    public class PointTypeConversion extends StrutsTypeConverter{
    	/**
    	 * 字符串转换成相应的对象类型
    	 */
    	@Override
    	public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
    		System.out.println("值是:"+arg1[0]);
    		String [] values=arg1[0].split(",");
    		Point p=new Point();
    		p.setX(Float.parseFloat(values[0]));
    		p.setY(Float.parseFloat(values[1]));
    		return p;
    	}
    	/**
    	 * 由对象转换成相应的字符串
    	 */
    	@Override
    	public String convertToString(Map arg0, Object arg1) {
    		Point point=(Point) arg1;
    		return "[经坐标:"+point.getX()+",纬坐标:"+point.getY()+"]";
    	}
    }
    
    

    三.二.五 编写类型转换文件

    MyAction2-conversion.properties 文件

    ##Action属性=全限定名称
    point=com.yjl.conversion.PointTypeConversion
    

    三.二.六 编写前端页面

    三.二.六.一 编写 /content/mypoint.jsp

    <s:form action="MyAction2" method="post" namespace="/">
    		点:<input type="text" name="point">
    		<s:submit value="提交" />
    </s:form>
    

    输入的格式用 , 进行分隔 。

    三.二.六.二 编写/content/show2.jsp

    <body>
    <s:property value="point"/>
    </body>
    

    三.二.七 验证

    输入网址: http://localhost:8080/Struts_Converter/mypoint

    输入郑州坐标: 113.62,34.75

    有图片

    点击确定按钮:

    控制台打印输出:

    有图片

    前端页面显示:

    有图片

    通过 StrutsTypeConverter 方式,也实现了类型转换的效果。

    四. 全局类型转换

    上面的方式 ,都是局部类型转换, 而自定义的类型,一般是在整个项目中通用的,故常常使用的是 全局类型转换。 JDK自带的类,一般用局部类型转换,重新设计。

    全局类型转换,与局部类型转换差不多,只是 局部的,写得是ActionName,

    而全局的,必须是 xwork-conversion.properites 文件名。

    另外,局部的是: Action属性名=要转换的类型转换器的全限定名称,

    而全局的是: 自定义的类全限定名称=要转换的类型转换器的全限定名称

    需要放置在 src 目录下。

    配置 Point 类的全局类型转换:

    放置在 src目录下, 文件名称为: xwork-conversion.properties

    内容为:

    
    ##自定义的类全限定名称=要转换的类型转换器的全限定名称 
    ## 对Point 类进行转换
    com.yjl.pojo.Point=com.yjl.conversion.PointTypeConversion
    

    提示: 当对一个自定义类型,既使用局部类型转换器,又使用全局类型转换时,会报错。

    本章节的代码链接为:

    链接:https://pan.baidu.com/s/1vp9oE2FZCLfFM-JueaSM7g 
    提取码:3ftv
    

    谢谢您的观看!!!

  • 相关阅读:
    JSON获取地址
    Java的selenium代码随笔(8)
    Java的selenium代码随笔(7)
    Java的selenium代码随笔(6)
    MySql插入点数据
    Win7系统用户文件夹多出一个Administrator.xxx开头的文件怎么解决
    Android Studio导入第三方类库的方法
    转:eclipse 设置Java快捷键补全
    解决android studio引用远程仓库下载慢(JCenter下载慢)
    AndroidStudio下载地址
  • 原文地址:https://www.cnblogs.com/yjltx/p/13071878.html
Copyright © 2011-2022 走看看