首页 > 学院 > 开发设计 > 正文

Struts2-10 类型转换

2019-11-08 19:38:42
字体:
来源:转载
供稿:网友

  MVC框架具有将字符串请求参数转换为响应数据类型的功能,而Struts2.0作为MVC框架的实现者,理所当然提供了类型转换机制,概述如下:

HTTP没有“类型”的概念,表单输入的只可能是字符串或字符串数组;Struts2从表单到Action对象的类型转换即是从字符串到非字符串的;Struts2的params拦截器在将请求参数映射到Action对象属性时,可自动完成字符串和基本数据类型间的转换。

一、类型转换错误消息的显示与定制

1.1 类型转换错误

  ConversionError拦截器作为默认拦截器栈的一员,负责添加与类型转换有关的出错消息(前提是Action类实现了ValidationAware接口)和保存各请求参数的原始值。     若字段标签使用非simple主题,则类型转换错误消息为:”Invalid field value for field fieldName”。

  如果类型转换发生错误,则

若Action类未实现ValidationAware接口:Struts2发生类型转换错误时,仍会继续调用其Action方法,就好像什么都没发生一样;若Action类实现了ValidationAware接口:Struts2发生类型转换错误时,不会继续调用其Action方法;而将检查相关action元素的声明是否包含name=input的result元素,若有则将控制权转交给该元素,否则抛出异常。注意:可以直接继承于实现了ValidationAware接口的ActionSupport类来代替实现ValidationAware接口。

1.2 覆盖默认错误信息

新建属性文件ActionClassName.PRoperties,放在Action类所在包中;添加键值对:invalid.fieldvalue.fieldName=Custome error message。

1.3 强制显示错误信息

  如果表单是simple主题,则不会自动显示错误消息。解决方案如下:

使用EL或OGNL表达式显示:${fieldErrors.age[0]},即通过debug标签可知,类型转换出错时在值栈的Action对象中有一个类型为Map<String, List<String>>的fieldErrors属性;使用s:fielderror标签来显示:<s:fielderror fieldName="fieldname"></s:fielderror>,即使用其fieldName属性显示指定字段的错误信息。

  问题:若是simple主题,且用s:fielderror标签来显示错误消息,则该消息包含在一个ul、li、span中,影响页面排版,如何去除?

在src下新建template.simple包,并新建fielderror.ftl文件;将Struts2核心包/template/simple/fielderror.ftl文件内容复制到新建fielderror.ftl文件中;剔除掉影响页面排版的ul、li、span部分即可。

二、自定义类型转换器

  因为Struts2不能自动完成字符串到非基本数据类型的转换,故需要定制类型转换器,主要包括开发类型转换器类和配置类型转换器两部分;具体如下:

2.1 开发类型转换器类

  自定义类型转换器必须实现ongl.TypeConverter接口或该接口某种具体实现类进行扩展,常扩展StrutsTypeConverter类即可。

2.2 配置类型转换器

(1)基于字段的配置   该方式可以为某Model类(可能是Action也可能是javaBean) 的各个属性分别配置一个自定义类型转换器;配置方法如下:

新建属性文件ModelClassName-conversion.properties,放在Model类所在包下;添加键值对:字段名=类型转换器的全类名;注意:第一次使用该转换器时即创建实例(单实例的)……

(2)基于类型的配置   该方式为整个应用中所有Model类的各个属性均配置同一个自定义类型转换器,配置方法如下:

在src目录下新建xwork-conversion.properties文件;添加键值对:待转换的类型=类型转换器的全类名;注意:在当前Struts2应用被加载时创建实例(创建两次)……

2.3 实现自定义的时间类型转换器

  要求:时间pattern需要以web应用初始化参数的形式配置在web.xml中,且当类型转换失败给出自定义信息。      web.xml中配置初始化参数如下:

<context-param> <param-name>pattern</param-name> <param-value>yyyy-mm-dd hh:mm:ss</param-value></context-param>

  类型转换器DateConverter.java代码如下:

package com.qiaobc.struts.converter;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..."); // 获取应用程序的初始化参数 /** * 基于字段的配置采用如下方法获取初始化参数,因其在第一次使用类型转换器时创建实例 */ // ServletContext servletContext = ServletActionContext.getServletContext(); // String dateStr = servletContext.getInitParameter("pattern"); // dateFormat = new SimpleDateFormat(dateStr); } /** * 基于类型的配置采用如下方法获取初始化参数,因其在应用加载时即创建实例 */ public DateFormat getdDateFormat() { if(dateFormat == null) { ServletContext servletContext = ServletActionContext.getServletContext(); String dateStr = servletContext.getInitParameter("pattern"); dateFormat = new SimpleDateFormat(dateStr); } 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) { // 将values[0]转换为Date型 try { // 基于字段的配置采用如下方法 // return dateFormat.parse(values[0]); // 基于类型的配置采用如下方法 return getdDateFormat().parse(values[0]); } 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); } // 未转换成功则返回null return null; }}

三、类型转换器与复杂属性&集合的协同使用

  类型转换器与复杂属性协同使用的基本原理图如下所示: 这里写图片描述   类型转换器与集合协同使用的基本原理图如下所示: 这里写图片描述


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表