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)