您的位置:首页 > 编程语言 > Java开发

Struts2(十四):类型转换

2017-07-21 21:39 363 查看
    从一个HTML表单到一个Action对象,类型转换是从字符串到非字符串

    在Struts2中,把请求参数映射到action属性的工作由Parameters拦截器负责,它是默认的defaultStack拦截器中的一员。Parmeters拦截器可以自动完成字符串与基本数据类型之间的转换。

一,类型转换失败

1.类型转换失败:

 如果Action没有实现ValidationAware接口:类型转换错误,仍会继续调用Action方法
 如果Action实现了ValidationAware接口:类型转换错误,不会继续调用Action方法。Struts2将检查相关的action元素是否包含着一个name=input的result。如果有Struts将把控制权交给result元素。如果没有result元素,Struts2将会抛出一个异常。

因为ActionSupport实现了ValidationAware接口,所有可以继承ActionSupport类

2.覆盖错误消息

(1)  ConversionError拦截器负责添加与类型转换有关的出错消息和保存各请求参数的原始值(默认default拦截器中的一员),前提是Action要实现了ValidationAware接口

(2)若字段标签使用的不是 Simple 主题, 则非法输入字段将导致一条有着以下格式的出错消息: Invalid field value for valid fieldName.

 (3)覆盖错误消息:

 在对应的Action的包下建立ActionClassName.propreties文件
在属性文件中添加如下键值对,invalid.fieldvalue.fieldName=Custom error message

3.如果是Simple主题,会显示错误消息?如果不显示,怎么办?

    (1)Simple主题,不会显示错误消息。

    (2)通过debug标签,可知转换出错,则在值栈的Action(实现了ValidationAware接口)对象中有一个fieldErrors属性。该属性为Map<String,List<String>>键:字段(属性名),值:错误信息组成的List。所以使用EL或OGNL表达式来显示错误信息:${fieldErrors.age[0]}

    (3)可以通过<s:fielderror fieldName="fieldNmae"></s:fielderror>。

          a:  使用标签显示错误信息,信息在一个ul,li,span中,如何去除ul,li,span?

                在 template.simple 下面的 fielderror.ftl 定义了 simple 主题下, s:fielderror 标签显示错误消息的样式. 所以修改该配置文件即可. 在 src 下新建  template.simple 包, 新建 fielderror.ftl 文件, 把原生的 fielderror.ftl 中的内容复制到新建的 fielderror.ftl 中, 然后剔除 ul, li, span 部分即可. 

4.改变样式:

   每一条出错消息都被打包在一个 HTML span 元素里, 可以通过覆盖其行标为 errorMessage 的那个 css 样式来改变出错消息的格式.  

二,自定义类型转换器

1.为什么自定义类型转换器?

   因为Struts2不能自动完成字符串到引用类型的转换(如String与Date),只能完成字符串与基本数据的转换,如String与int

2.步骤:

    (1)开发类型转换器的类:

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



        代码举例:是一个字符与日期之间的转换

package action;

import org.apache.struts2.util.DateFormatter;
import org.apache.struts2.util.StrutsTypeConverter;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

public class DateConverter extends StrutsTypeConverter {
private DateFormat dateFormat;
public  DateConverter()
{
System.out.println("成功");
dateFormat=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
}
@Override
public Object convertFromString(Map map, String[] strings, Class aClass) {
if(aClass== Date.class)
{
if(strings!=null && strings.length>0)
{
String value=strings[0];
try{
return dateFormat.parseObject(value);
}catch (ParseException e)
{
e.printStackTrace();
}
}
}
//没有转换成功
return strings;
}

@Override
public String convertToString(Map map, Object o) {
if(o instanceof Date)
{
Date date=(Date)o;
return dateFormat.format(date);
}
return null;
}
}


    (2)配置类型转换器

        -> 基于字段的配置: 

 在字段所在的Model(可能是Action,可能是一个JavaBean)的包下,新建一个ModelClassName-converter.properties
 在文件中输入键值对:fieldName-类型转换器的全类名
第一次使用该转换器时创建实例
类型转换是单实例



         ->基于类型的配置:

在src下新建xwork-conversion-properties
 键入:待转换的类型=类型转化器的全类名
在当前Struts2应用未加载时创建实例,不是单实例



注意:

如果参数在web.xml文件中初始化:

<context-param>
<param-name>pattern</param-name>
<param-value>yyyy-MM-dd hh:mm:ss</param-value>
</context-param>
则使用类型配置会出错,因为基于类型配置时是在Struts2应用未加载时创建实例,这时候并没有获取到web.xml的参数,转换会失败

代码更改:

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...");
}

public DateFormat getDateFormat(){
if(dateFormat == null){
//获取当前 WEB 应用的初始化参数 pattern
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 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 getDateFormat().format(date);
}

//若转换失败返回 null
return null;
}

}


三,类型转换与复杂属性

(1)form标签的name属性可以被映射到一个属性的属性



(2)Struts2还允许填充Collection里的对象,这常见于需要快速录入批量数据的场合

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  struts2 类型转换