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

谢谢您的观看!!!

posted @ 2020-06-09 12:34  两个蝴蝶飞  阅读(187)  评论(0编辑  收藏  举报