OGNL创建和配置自定义日期类型转换器

OGNL

OGNL 中文名 对象图导航语言Object-Graph Navigation Language 的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。

基于OGNL的类型转换器

Struts2的类型转换器都需要实现一个TypeConverter接口,该接口位于ognl.jar包内,也是就Struts2框架的转换器使用了OGNL技术。该接口定义了一个convertValue()方法,实现该接口的类型转换器实现类都需要重写该方法来进行类型转换。OGNL还提供了一个实现TypeConverter接口的类DefaultTypeConverter,开发者只要继承该类,就可以开发类型转换器的实现类。

DefaultTypeConverter类的子类需要重写convertValue()方法,来实现字符串类型与复合类型之间的双向转换。convertValue()方法有三个参数:Map context:该参数为类型转换环境的上下文内容;Object value:该参数为需要转换的参数;Class toType:该参数指的是转换目标的类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class PointConverter extends DefaultTypeConverter {
public Object convertValue(Map context,Object value,Class toType){
System.out.println("正在转换...");
if(toType==Point.class){
String[] p=(String[])value;
Point point=new Point();
String[] pp=p[0].split(",");
point.setX(pp[0]);
point.setY(pp[1]);
return point;
}
else if(toType==String.class){
Point point=(Point) value;
return "<"+point.getX()+","+point.getY()+">";
}
return null;
}
}

convertValue()方法是通过toType的类型判断来实现双向转换的

基于Struts2的类型转换器

Struts2框架提供了一个类型转换器的StrutsTypeConverter抽象类,开发者可以继承该类来开发自定义的类型转换器实现类。 该抽象类实际上继承了DefaultTypeConverter类,在该类的基础上进行了简化。StrutsTypeConverter抽象类是Struts2框架中类型转换器的基础,该类中提供了两个抽象方法,这两个抽象方法分别实现“form字符串参数-Struts复合类型”之间的双向转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class PointConverter2 extends StrutsTypeConverter {
//定义convertFromString方法
@Override
public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
// TODO Auto-generated method stub
System.out.println("正在转换:从字符串转换到复合类型...");
Point point=new Point();
String[] pp=arg1[0].split(",");
point.setX(pp[0]);
point.setY(pp[1]);
return point;
}

//定义convertToString方法
@Override
public String convertToString(Map arg0, Object arg1) {
// TODO Auto-generated method stub
Point point=(Point) arg1;
return "<"+point.getX()+","+point.getY()+">";
}
}

自定义日期类型转换器例子

环境

idea
Java
Maven
Struts2
Tomcat

pom.xml 配置 dependencies

1
2
3
4
5
6
7
8
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-core -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.16.3</version>
</dependency>
</dependencies>

util包 DateConverter类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.util;

import com.opensymphony.xwork2.conversion.TypeConversionException;
import org.apache.struts2.util.StrutsTypeConverter;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

public class DateConverter extends StrutsTypeConverter {
//支持转换的多种日期格式,可增加时间格式
private final DateFormat[] dfs = {
new SimpleDateFormat("yyyy年MM月dd日"),
new SimpleDateFormat("yyyy/MM/dd"),
new SimpleDateFormat("yyyy-MM-dd"),
new SimpleDateFormat("yyyy@MM@dd")
};

/**
* 将指定格式字符串转换为日期类型
*
* @param map 类型转换环境的上下文内容
* @param strings 需要转换的参数
* @param aClass 转换目标的类型
* @return
*/
public Object convertFromString(Map map, String[] strings, Class aClass) {
String dateStr = strings[0]; //获取日期的字符串
for (int i = 0; i < dfs.length; i++) { //遍历日期支持格式,进行转换
try {
return dfs[i].parse(dateStr);
} catch (Exception e) {
continue;
}
}
//如果遍历完毕后仍没有转换成功,表明出现转换异常
throw new TypeConversionException();
}

/**
* 将日期转换为指定格式字符串
*
* @param map
* @param o
* @return
*/
public String convertToString(Map map, Object o) {
Date date = (Date) o;
//输出的格式是yyyy-MM-dd
return new SimpleDateFormat("yyyy-MM-dd").format(date);
}
}

action包 DateAction类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ValidationAware;

import java.util.Date;

public class DateAction extends ActionSupport implements ValidationAware {
public Date getTime() {
return time;
}

public void setTime(Date time) {
this.time = time;
}

private Date time;

@Override
public String execute() throws Exception {
return SUCCESS;
}
}

xwork-conversion.properties 配置

转换类全名=类型转换器类全名
1
java.util.Date=com.util.DateConverter

测试页面 index.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="format.action" method="post">
日期类型转换器:
<input type="text" name="time" value="1993@12@24"/>
<input type="submit" value="提交"/>
</form>
<s:property value="time"/>
<s:fielderror/>
</body>
</html>

web.xml 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>Struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

struts.xml 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
<!--value 的 message 为指定根目录的 message.properties 配置文件-->
<constant name="struts.custom.i18n.resources" value="message"/>
<package name="default" extends="struts-default">
<action name="format" class="com.action.DateAction">
<result>index.jsp</result>
<result name="input">index.jsp</result>
</action>
</package>
</struts>

message.properties 修改错误信息配置

1
xwork.default.invalid.fieldvalue=\u5b57\u6bb5"{0}"\u7684\u503c\u65e0\u6548
`\u5b57\u6bb5"{0}"\u7684\u503c\u65e0\u6548` 为 Unicode编码 `字段"{0}"的值无效` 配置文件 `中文` 需要转换成 `Unicode编码`

Unicode编码转换网站