首页 > 代码库 > 从源代码剖析Struts2中用户自定义配置转换器的两种方式——基于字段的配置转换器和基于类型的配置转换器(解决了实际系统中,因没有区分这两种工作方式的生命周期而引起的异常错误问题)
从源代码剖析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 ActionSupportimplements ModelDriven<Customer>{
private static final long serialVersionUID = 1L;
public Stringexecute(){ System.out.println("model: " +model); return"success"; }
private Customermodel;
@Override public Customer getModel() { model = new Customer(); returnmodel; }
}
|
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 DateFormatdateFormat;
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); }
returndateFormat; }
@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 = http://www.mamicode.com/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:formaction="testConversion"theme="simple"> Age: <s:textfieldname="age"label="Age"></s:textfield> ${fieldErrors.age[0] } ^<s:fielderrorfieldName="age"></s:fielderror> <br><br>
Birth: <s:textfieldname="birth"></s:textfield> <s:fielderrorfieldName="birth"></s:fielderror> <br><br>
<s:submit></s:submit> </s:form> |
Struts.xml的文件的信息:
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEstruts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts> <packagename="default"namespace="/"extends="struts-default"> <actionname="testConversion"class="com.atguigu.struts2.app.ConversionAction"> <result>/success.jsp</result> <resultname="input">/index.jsp</result> </action>
<actionname="testComplextProperty"class="com.atguigu.struts2.app.TestComplextPropertyAction"> <result>/success.jsp</result> </action>
<actionname="testConversion2"class="com.atguigu.struts2.app.TestCollectionAction"> <result>/success.jsp</result> </action> </package> </struts> |
<debug></debug>信息:
提交之后跳转到如下页面信息如下:
从源代码剖析Struts2中用户自定义配置转换器的两种方式——基于字段的配置转换器和基于类型的配置转换器(解决了实际系统中,因没有区分这两种工作方式的生命周期而引起的异常错误问题)