勿以恶小而为之,勿以善小而不为--------------------------刘备
劝诸君,多行善事积福报,莫作恶
上一章简单介绍了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 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文件
/WEB-INF/content/{1}.jsp
二.二.三 自定义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 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级别的话,
- 文件名称必须是: Action的名称-conversion-properties
- 必须要与Action在同一目录下
- 内容是: Action中的属性=要转换的自定义类型转换器的全限定名称
如果是全局级别的话:
- 文件名称 必须是 xwork-conversion.properites
- 必须放置在 src 目录,即classpath 目录下
- 内容是: 自定义的类全限定名称=要转换的类型转换器的全限定名称
故: 对于DateTypeConversion 类型转换器来说, 其对应的级别配置文件为:
MyAction1-conversion.properties, 需要放置在 com.yjl.web.action 包下.
内容是:
##Action属性=全限定名称
birthday=com.yjl.conversion.DateTypeConversion
二.二.五 编写前端界面 /content/mydate.jsp
生日:
二.二.六 验证
启动服务器,进行相关的验证
输入网址: 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 文件
/WEB-INF/content/show.jsp
二.二.七.三 类型转换器和配置文件 MyAction1-conversion.property 保持不变
二.二.七.四 编写 /content/show.jsp 页面
二.二.七.五 重启服务器,进行验证
输入网址: 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
/WEB-INF/content/show2.jsp
三.二.四 编写类型转换器 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
点:
输入的格式用 , 进行分隔 。
三.二.六.二 编写/content/show2.jsp
三.二.七 验证
输入网址: 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
谢谢您的观看!!!