从源代码剖析Struts2中用户自定义配置转换器的两种方式——基于字段的配置转换器和基于类型的配置转换器(解决了实际系统中,因没有区分这两种工作方式的生命周期而引起的异常错误问题)

自定义类型转换器必须实现ongl.TypeConverter接口或对这个接口的某种具体实现做扩展

<<interface>>com.opensymphony.xwork2.conversion.TypeConverter
 à com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter
 à org.apache.struts2.util.StrutsTypeConverter

接口及类进行解析

TypeConverter(接口)

Interface for accessing the type conversion facilities within a context. This interface was copied from OGNL's TypeConverter

 

DefaultTypeConverter

public class DefaultTypeConverter implements TypeConverter

Default type conversion. Converts among numeric types and also strings. Contains the basic type mapping code from OGNL.

 

StrutsTypeConverter

public abstract class StrutsTypeConverter extends DefaultTypeConverter

Base class for type converters used in Struts. This class provides two abstract methods that are used to convert both to and from strings -- the critical functionality that is core to Struts's type coversion system.

 

下面是源代码中上面各接口及类相关的方法及属性轮廓图:


源问题: 如何自定义类型转换器 ?  

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

         2、如何定义类型转换器:

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

         II.配置类型转换器:

 

解决源问题的方法:配置类型转换器两种方式

         ①. 基于字段的配置类型转换器:

                   >在字段所在的 Model(可能是 Action, 可能是一个 JavaBean) 的包下, 新建一个 ModelClassName-conversion.properties 文件

                   >在该文件中输入键值对: fieldName=类型转换器的全类名.

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

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


         ②. 基于类型的配置类型转换器:

                   >在 src 下新建 xwork-conversion.properties

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

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


细节注意:.properties配置文件的位置(该文件存放的位置)


现在看看文件的结构信息:


ConversionAction.java文件

package com.atguigu.struts2.app;

 

import com.atguigu.struts2.model.Customer;

import com.opensymphony.xwork2.ActionSupport;

import com.opensymphony.xwork2.ModelDriven;

 

public class ConversionAction extends ActionSupport implements ModelDriven<Customer>{

 

    private static final long serialVersionUID = 1L;

   

    public String execute(){

       System.out.println("model: " + model);

       return "success";

    }

   

    private Customer model;

 

    @Override

    public Customer getModel() {

       model = new Customer();

       return model;

    }

   

}

 

 

DateConverter.java文件

package com.atguigu.struts2.app.converters;

 

import java.text.DateFormat;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Map;

 

import javax.servlet.ServletContext;

 

import org.apache.struts2.ServletActionContext;

import org.apache.struts2.util.StrutsTypeConverter;

 

public class DateConverter extends StrutsTypeConverter {

 

    private DateFormat dateFormat;

   

    public DateConverter() {

       System.out.println("DateConverter's constructor...");

      

       /**

       //应用加载时机不同而产生的异常(NullException

       //获取当前 WEB 应用的初始化参数 pattern(该参数在WEB-INF下的web.xml文件中)

       //这种方法使用/struts2-6/Customer-conversion.properties配置文件

       //Customer-conversion.properties配置文件的内容:

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

       ServletContext servletContext = ServletActionContext.getServletContext();

       System.out.println(servletContext);

       String pattern = servletContext.getInitParameter("pattern");

       dateFormat = new SimpleDateFormat(pattern);

        *

        */

      

    }

   

    /**

     * 解决上面的问题,而重写的一个方法

     * @return

     */

    public DateFormat getDateFormat(){

       if(dateFormat == null){

           //获取当前 WEB 应用的初始化参数 pattern(该参数在WEB-INF下的web.xml文件中)

           //第一次用的时候获取,并加载相关的信息

           //这种方法是使用/struts2-6/src/xwork-conversion.properties配置文件

           //xwork-conversion.properties配置文件的内容:

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

           ServletContext servletContext = ServletActionContext.getServletContext();

           System.out.println(servletContext);

           String pattern = servletContext.getInitParameter("pattern");

           dateFormat = new SimpleDateFormat(pattern);

       }

      

       return dateFormat;

    }

   

    @Override

    public Object convertFromString(Map context, String[] values, Class toClass) {

      

       System.out.println("convertFromString...");

      

       if(toClass == Date.class){

           if(values != null && values.length > 0){

              String value = values[0];

              try {

                  // return dateFormat.parseObject(value);

                  return getDateFormat().parseObject(value);

              } catch (ParseException e) {

                  e.printStackTrace();

              }

           }

       }

      

       //若没有转换成功, 则返回 values

       return values;

    }

 

    @Override

    public String convertToString(Map context, Object o) {

      

       System.out.println("convertToString...");

      

       if(o instanceof Date){

           Date date = (Date) o;

           //return dateFormat.format(date);

           return getDateFormat().format(date);

       }

      

       //若转换失败返回 null

       return null;

    }

 

}

 

 

显示页面的信息:

Index.jsp

<s:form action="testConversion" theme="simple">

       Age: <s:textfield name="age" label="Age"></s:textfield>

       ${fieldErrors.age[0] }

       ^<s:fielderror fieldName="age"></s:fielderror>

       <br><br>

      

       Birth: <s:textfield name="birth"></s:textfield>

       <s:fielderror fieldName="birth"></s:fielderror>

       <br><br>

      

       <s:submit></s:submit>

    </s:form>

 

Struts.xml的文件的信息:

<?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>

    <package name="default" namespace="/" extends="struts-default">

       <action name="testConversion" class="com.atguigu.struts2.app.ConversionAction">

           <result>/success.jsp</result>

           <result name="input">/index.jsp</result>

       </action>

      

       <action name="testComplextProperty" class="com.atguigu.struts2.app.TestComplextPropertyAction">

           <result>/success.jsp</result>

       </action>

      

       <action name="testConversion2" class="com.atguigu.struts2.app.TestCollectionAction">

           <result>/success.jsp</result>

       </action>

    </package>

</struts>

<debug></debug>信息:


提交之后跳转到如下页面信息如下:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值