Struts2类型转换(二)-自定义类型转换器

一、自定义类型转换器

1). 为什么需要自定义的类型转换器 ?

因为Struts不能自动完成字符串到引用类型的转换。

2). 如何定义类型转换器?

I. 开发类型转换器的类: 扩展 StrutsTypeConverter 类;

II. 配置类型转换器。

有两种配置方式
①. 基于字段的配置:
> 在字段所在的 Model(可能是 Action,也可能是一个JavaBean) 的包下, 新建一个 ModelClassName-conversion.properties 文件
> 在该文件中输入键值对: fieldName=类型转换器的全类名。(fieldName即带转换字段的名称)

> 两个相关结论:

  ·第一次使用该转换器时创建实例.

    ·类型转换器是单实例的!

②. 基于类型的配置:
> 在 src 下新建 xwork-conversion.properties文件

> 键入: 待转换的类型=类型转换器的全类名.

> 两个相关结论:

  ·在当前 Struts2 应用被加载时创建实例.

  · 在这种情况下类型转换器被创建了两次,即不是单实例的(了解 )

二、示例

1)基于字段的配置方式

修改“Struts2类型转换(一)”的JSP代码如下:(JSP页面的名称为index.jsp)

 1 <s:form action="testConversion" theme="simple">
 2     Age: <s:textfield name="age" label="Age"></s:textfield>
 3     ${fieldErrors.age[0]}
 4     <s:fielderror fieldName="age"></s:fielderror>
 5     <br><br>
 6
 7     Birth: <s:textfield name="birth"></s:textfield>
 8     <s:fielderror fieldName="birth"></s:fielderror>
 9     <br><br>
10     <s:submit></s:submit>
11 </s:form>

当Model为一个Action时,Java代码如下:

package com.atguigu.struts2.app;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

public class ConversionAction extends ActionSupport{

    private int age;
    private Date birth;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public String execute(){
        System.out.println("age: " + age);
        System.out.println("birth: " + birth);
        return "success";
    }

}

定义String与Date之间的类型转换器如下:

 1 package com.atguigu.struts2.app.converters;
 2
 3 import java.text.DateFormat;
 4 import java.text.ParseException;
 5 import java.text.SimpleDateFormat;
 6 import java.util.Date;
 7 import java.util.Map;
 8
 9 import javax.servlet.ServletContext;
10
11 import org.apache.struts2.ServletActionContext;
12 import org.apache.struts2.util.StrutsTypeConverter;
13
14 public class DateConverter extends StrutsTypeConverter {
15
16     private DateFormat dateFormat;
17
18     public DateConverter() {
19         System.out.println("DateConverter‘s constructor...");
20
21          //获取当前 WEB 应用的初始化参数 pattern
22          /**
23          * web.xml的根节点中添加有如下配置:
24          * <context-param>
25          *         <param-name>pattern</param-name>
26          *        <param-value>yyyy-MM-dd HH:mm:ss</param-value>
27          * </context-param>
28          */
29         ServletContext servletContext = ServletActionContext.getServletContext();
30         System.out.println(servletContext);
31         String pattern = servletContext.getInitParameter("pattern");
32         dateFormat = new SimpleDateFormat(pattern);
33     }
34
35     @Override
36     public Object convertFromString(Map context, String[] values, Class toClass) {
37
38         System.out.println("convertFromString...");
39
40         if(toClass == Date.class){
41             if(values != null && values.length > 0){
42                 String value = values[0];
43                 try {
44                     return dateFormat.parseObject(value);
45                 } catch (ParseException e) {
46                     e.printStackTrace();
47                 }
48             }
49         }
50
51         //若没有转换成功, 则返回 values
52         return values;
53     }
54
55     @Override
56     public String convertToString(Map context, Object o) {
57
58         System.out.println("convertToString...");
59
60         if(o instanceof Date){
61             Date date = (Date) o;
62             return dateFormat.format(date);
63         }
64
65         //若转换失败返回 null
66         return null;
67     }
68
69 }    

对应的配置文件名称为:ConversionAction-conversion.properties,配置内容如下:

birth=com.atguigu.struts2.app.converters.DateConverter

当Model为一个JavaBean时,Java代码如下:

 1 //JavaBean为Customer
 2 package com.atguigu.struts2.model;
 3
 4 import java.util.Date;
 5
 6 public class Customer {
 7
 8     private int age;
 9
10     public void setAge(int age) {
11         this.age = age;
12     }
13
14     public int getAge() {
15         return age;
16     }
17
18     private Date birth;
19
20     public void setBirth(Date birth) {
21         this.birth = birth;
22     }
23
24     public Date getBirth() {
25         return birth;
26     }
27
28     @Override
29     public String toString() {
30         return "Customer [age=" + age + ", birth=" + birth + "]";
31     }
32
33 }
34
35 //Action代码,Action实现了ModelDriven接口
36 package com.atguigu.struts2.app;
37
38 import com.atguigu.struts2.model.Customer;
39 import com.opensymphony.xwork2.ActionSupport;
40 import com.opensymphony.xwork2.ModelDriven;
41
42 public class ConversionAction extends ActionSupport implements ModelDriven<Customer>{
43
44     public String execute(){
45         System.out.println("model: " + model);
46         return "success";
47     }
48
49     private Customer model;
50
51     @Override
52     public Customer getModel() {
53         model = new Customer();
54         return model;
55     }
56
57 }

对应的配置文件名称为:Customer-conversion.properties,配置内容如下:

birth=com.atguigu.struts2.app.converters.DateConverter

struts.xml中的基本配置如下:

<action name="testConversion" class="com.atguigu.struts2.app.ConversionAction">
    <result>/success.jsp</result>
    <result name="input">/index.jsp</result>
</action>

通过以上代码即可完成字符串与Date类型之间的类型转换工作。

2)基于类型的配置方式

在基于类型的配置方式中,JSP页面代码与Action的代码都与基于字段的配置方式的代码相同,但是在类型转换器的代码有所不同:

 1 package com.atguigu.struts2.app.converters;
 2
 3 import java.text.DateFormat;
 4 import java.text.ParseException;
 5 import java.text.SimpleDateFormat;
 6 import java.util.Date;
 7 import java.util.Map;
 8
 9 import javax.servlet.ServletContext;
10
11 import org.apache.struts2.ServletActionContext;
12 import org.apache.struts2.util.StrutsTypeConverter;
13
14 public class DateConverter extends StrutsTypeConverter {
15
16     private DateFormat dateFormat;
17
18     public DateConverter() {
19         System.out.println("DateConverter‘s constructor...");
20     }
21
22     public DateFormat getDateFormat(){
23         if(dateFormat == null){
24             //获取当前 WEB 应用的初始化参数 pattern
25             /**
26              * web.xml的根节点中添加如下配置:
27              * <context-param>
28              *         <param-name>pattern</param-name>
29              *        <param-value>yyyy-MM-dd HH:mm:ss</param-value>
30              * </context-param>
31              */
32             ServletContext servletContext = ServletActionContext.getServletContext();
33             System.out.println(servletContext);
34             String pattern = servletContext.getInitParameter("pattern");
35             dateFormat = new SimpleDateFormat(pattern);
36         }
37
38         return dateFormat;
39     }
40
41     @Override
42     public Object convertFromString(Map context, String[] values, Class toClass) {
43
44         System.out.println("convertFromString...");
45
46         if(toClass == Date.class){
47             if(values != null && values.length > 0){
48                 String value = values[0];
49                 try {
50                     return getDateFormat().parseObject(value);
51                 } catch (ParseException e) {
52                     e.printStackTrace();
53                 }
54             }
55         }
56
57         //若没有转换成功, 则返回 values
58         return values;
59     }
60
61     @Override
62     public String convertToString(Map context, Object o) {
63
64         System.out.println("convertToString...");
65
66         if(o instanceof Date){
67             Date date = (Date) o;
68             return getDateFormat().format(date);
69         }
70
71         //若转换失败返回 null
72         return null;
73     }
74
75 }    

注意:关于两种配置方法情况下类型转换器创建时机不同引出的问题

在基于字段配置的方式下,类型转换器的创建时机是在第一次使用该类型转换器的时候,因此对于dateFormat的初始化工作可以在其构造方法中完成,而在基于类型的配置方式下,类型转换器是在Struts2应用被加载时创建的,由于这时ServletContext对象还未被装载到ServletActionContext中,因此获取到的servletContext对象为null,就不能在类型转换器的构造方法中对dateFormat进行初始化,因此要在使用时判断dateFormat是否为null,然后在执行操作。

基于类型配置方式的配置文件名称为:xwork-conversion.properties,配置内容如下:

java.util.Date=com.atguigu.struts2.app.converters.DateConverter

三、关于示例的说明

以上示例中对于字符串与java.util.Date类型之间的转换,在教程中所演示时无论在页面输入日期格式为“yyyy-MM-dd HH:mm:ss”,还是"yyyy/MM/dd HH:mm:ss",不使用类型转换器Struts2框架都无法正常进行转换,而自己在进行测试的时候,只要按照中文语言环境下的格式输入日期“yyyy-MM-dd”或"yyyy-MM-dd HH:mm:ss"都可以正常执行,而不需要使用类型转换器。

在网上查找后网友给出的相关解释及解决方法如下:

1)Struts2中转换Date类型的问题:http://polaris.blog.51cto.com/1146394/315403/

2)网友给出另一个解决方法:在struts.xml中定义参数:<constant name="struts.locale" value="zh_CN" />

注:该Struts2学习教程来自尚硅谷-佟刚-Struts2教程,感谢尚硅谷及佟刚老师的分享。

Struts2类型转换(二)-自定义类型转换器

时间: 2024-10-23 15:56:16

Struts2类型转换(二)-自定义类型转换器的相关文章

Struts2框架的自定义类型转换器

前言:对于java的基本数据类型及一些系统类(如Date类.集合类),Struts2提供了内置类型转换功能,但是也有一定的限制.所以就演示出自定义类型转换器 一.应用于局部类型转换器 eg.用户登录出生日期只能用2016-06-09的方式才能转化成功,那么2016/06/09就不能转换成功所以就引出来我们的自定义类型转换器 1首先我们将做准备工作 1)login.jsp注册页面 <%@ page language="java" import="java.util.*&q

[原创]java WEB学习笔记67:Struts2 学习之路-- 类型转换概述, 类型转换错误修改,如何自定义类型转换器

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

struts2自定义类型转换器

首先,何为struts2的类型转换器? 类型转换器的作用是将请求中的字符串或字符串数组参数与action中的对象进行相互转换. 一.大部分时候,使用struts2提供的类型转换器以及OGNL类型转换机制即可满足大部分类型转换需求.如: 类User.java package models; public class User { private String username; private String password; public String getUsername() { retur

struts2基础----&gt;自定义类型转换器

这一章,我们开始struts2中自定义类型转换器的学习. 自定义类型转换器 一.定义一个继承于StrutsTypeConverter的转换类: package com.huhx.converter; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import o

Struts2 自定义类型转换器

Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器 如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性 用date类型是可以接收到的,但是如果传的是20101112这样类型的字符串,用date类型是获取不到,并且会出现错误的,struts2提供了一 种类型转换器供我们使用. 以下为局部类型转换器的开发步骤a.首先要写一个类来继承DefaultTypeConverterb.然后覆盖convertValue

自定义struts2中action参数类型转换器

DateAction.java中代码如下: package com.itheima.action; import java.util.Date; public class DateAction { private Date time; public Date getTime() { return time; } public void setTime(Date time) { this.time = time; } public String execute() { return "succes

Struts2之自定义类型转换器

Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器 如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性用date类型是可以接收到的,但是如果传的是20101112这样类型的字符串,用date类型是获取不到,并且会出现错误的,struts2提供了一种类型转换器供我们使用. 以下为局部类型转换器的开发步骤a.首先要写一个类来继承DefaultTypeConverterb.然后覆盖convertValue这个

自定义类型转换器converter

作用:目前将日期转换成string,将string转换成我想要的类型   0509课件里讲 一.数据类型转换在web应用程序中,数据存在两个方向上的转换:1.当提交表单时  表单数据以字符串的形式提交给服务器,在服务器端转换成不同的Java数据类型 2.当需要在页面显示数据时  将不同的Java数据类型转换为对应的字符串格式显示输出 二.Struts2内置的类型转换Struts2内置了常用类型的自动转换功能,支持常见数据类型与字符串之间的转换 三.自定义类型转换1.编写自定义类型转换器,继承St

sruts2 自定义类型转换器

1.1.1    Struts2中自定义类型转换器:(了解) 类型转换的过程是双向的过程: JSP---->Action参数提交:String---Date. Action---->JSP数据回显:Date---String. 自定义类型转换器: * 1.实现TypeConverter * convertValue(java.util.Map<java.lang.String,java.lang.Object> context, java.lang.Object target, j