`

struts2之类型转换

 
阅读更多

 

从一个 HTML 表单到一个 Action 对象,类型转换是从字符串到非字符串。

HTTP 没有 “类型” 的概念,每一项表单输入只可能是一个字符串或一个字符串数组。在服务器端,必须把 String 转换为特定的数据类型。

在 struts2 中,把请求参数映射到 action  属性的工作由 params(com.opensymphony.xwork2.interceptor.ParametersInterceptor)拦截器负责, 它是默认的 defaultStack 拦截器中的一员。params拦截器可以自动完成字符串和基本数据类型之间转换。

 

类型转换错误

 

如果类型转换失败,系统如何处理?

 

若 Action 类没有实现 ValidationAware 接口: Struts 在遇到类型转换错误时仍会继续调用其 Action 方法,就好像什么都没发生一样。

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

 

类型转换错误消息的定制

 

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

若字段标签使用的不是 simple 主题,则非法输入字段将导致一条有着以下格式的出错消息:

 

Invalid field value for field "price".

 

覆盖默认的出错消息[定制出错消息的内容]

 

在对应的 Action 类所在的包中新建  ActionClassName.properties 文件,ClassName 即为包含着输入字段的 Action 类的类名。

在ActionClassName.properties 文件中添加如下键值对:

invalid.fieldvalue.fieldname=your error meesage

其中,fieldname为对应的属性的名称。

 

定制出错消息的样式

 

如果是 simple 主题, 还会自动显示错误消息吗? 如果不会显示, 怎么办 ?

1). 不会。还可以使用 s:fielderror 标签来显示. 可以通过 fieldName 属性显示指定字段的错误.

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

3) 若是 simple 主题, 且使用  <s:fielderror fieldName="age"></s:fielderror> 来显示错误消息, 则该消息在一个 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 样式来改变出错消息的格式。查看源代码可知,错误消息span标签有个class属性,其值为errorMessage。

5) 显示错误消息:如果是 simple 主题,系统默认不显示出错消息,需要通过 <s:fielderror fieldName=“filedname”></s:fielderror> 标签显示错误消息。其中,fieldname为实际的属性值。

 

定制类型转换器

 

为什么需要自定义的类型转换器 ?

 

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

 

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



  

在大多数类型转换器里, 需要提供从 String 类型到非 String 类型和与此相反的转换功能

在 StrutsTypeConverter 中有两个抽象方法:

 

 

在应用程序里使用一个自定义的类型转换器之前, 必须先对它进行配置。这种配置既可以基于字段,也可以基于类型:

 

基于字段配置

 

可以为某个 Model(该 Model 类也可能是 Action) 的各个属性分别配置一个自定义的转换器

1. 创建一个属性文件: ModelClassName-conversion.properties, 该文件需和相对应的 Model 类放在同一个目录下

2. 编辑属性文件: 

fieldname1=customConverter1

fieldname2=customConverter2

 

基于类型配置

在 WEB-INF/classes/ 目录下创建 xwork-conversion.properties 文件. 

在 xwork-conversion.properties 文件里把每一个需要进行类型转换的类与一个类型转换器关联起来

fullyQualifiedClassName=CustomConverter1

 

自定义类型转换器小结

 

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

II. 配置类型转换器:

    有两种方式

①. 基于字段的配置:

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

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

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

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

 

②. 基于类型的配置:

> 在 src 下新建 xwork-conversion.properties

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

> 在当前 Struts2 应用被加载时创建实例。不是单实例

 

示例 

 

要求如下:

实现自定义的时间类型转换器: 时间 pattern 需要以 web 应用的初始化参数配置在 web.xml 中 

 

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

   

若类型转换失败,给出自定义的信息。

 

1. 添加JSP页面

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>struts2之类型转换示例</title>
</head>
<body>
    
    <h1>struts2之类型转换示例</h1>
    
    <s:form name="order" action="order-commit.action" method="POST">
        <s:textfield name="id" label="订单编号"></s:textfield>
        <s:textfield name="name" label="订单名称"></s:textfield>
        <s:textfield name="price" label="订单价格"></s:textfield>
        <s:textfield name="createdate" label="订单日期"></s:textfield>
        <s:submit value="提交"></s:submit>
    </s:form>
    
</body>
</html>

  

 2. 添加模型和Action类

 

package org.rabbitx.web.struts2.example.dateconvert.action;

import java.util.Date;

public class Order {

	private int id;
	
	private String name;
	
	private double price;
	
	private Date createdate;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public Date getCreatedate() {
		return createdate;
	}

	public void setCreatedate(Date createdate) {
		this.createdate = createdate;
	}

}

 

 

package org.rabbitx.web.struts2.example.dateconvert.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;

public class OrderAction extends ActionSupport  implements Preparable,ModelDriven<Order>{

	private static final long serialVersionUID = 7623439468123773653L;

	private Order order;
	
	public String commit()
	{
		System.out.println("------OrderAction----------order----------");
		System.out.println("order: " + order);
		return SUCCESS;
	}

	@Override
	public void prepare() throws Exception {
		order = new Order();		
	}
	
	@Override
	public Order getModel() {
		return order;
	}
}

 

 3. 配置action

 

    <package name="order" extends="struts-default">
        <default-interceptor-ref name="paramsPrepareParamsStack"/>
        <action name="order-*" 
                class="org.rabbitx.web.struts2.example.dateconvert.action.OrderAction"
                method="{1}">
            <result name="success">/success.jsp</result>
            <result name="input">/exampleDateConvert/order.jsp</result>
        </action>
    </package>

 

 4. 添加类型转换器

 

package org.rabbitx.web.struts2.example.dateconvert.action;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
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 SimpleDateFormat dateFormat;
	
	public DateConverter()
	{
		System.out.println("----DateConverter------constructor-------------");
		//如果基于类型配置转换器,则不能在构造器中调用此方法生成SimpleDateFormat对象。
		//因为,基于类型配置的转换器会在web应用时加载(实例被创建),而加载全局转换器时,ServletContext对象还未创建,会发生空指针异常。
		//解决的办法是系统第一次调用转换方法的时候在创建SimpleDateFormat对象
		//createDateFormat();
	}
	
	public void createDateFormat()
	{
		if(dateFormat == null)
		{
			ServletContext context = ServletActionContext.getServletContext();
			String datePattern = context.getInitParameter("datePattern");
			Locale locale = Locale.getDefault();
			dateFormat = new SimpleDateFormat(datePattern,locale);
		}
	}
	
	@SuppressWarnings("rawtypes")
	@Override
	public Object convertFromString(Map context, String[] values, Class toClass) {
        try
        {
        	if(toClass == Date.class)
        	{
        		return getDateFormat().parse(values[0]);
        	}
		}
        catch (ParseException e) 
        {
		    e.printStackTrace();
		}
		return values;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public String convertToString(Map context, Object o) {
		if(o instanceof Date)
		{
			return getDateFormat().format((Date)o);
		}
		return null;
	}

	public SimpleDateFormat getDateFormat() {
		createDateFormat();
		return dateFormat;
	}

	public void setDateFormat(SimpleDateFormat dateFormat) {
		this.dateFormat = dateFormat;
	}

}

 

 5. 基于属性或基于类型配置类型转换器

 

 5.1 基于属性:在与模型Order相同目录下创建Order-conversion.properties文件并添加下面内容:

 

createdate=org.rabbitx.web.struts2.example.dateconvert.action.DateConverter

  

5.2 基于类型:在src目录下创建xwork-conversion.properties文件并添加下面内容:

 

java.util.Date=org.rabbitx.web.struts2.example.dateconvert.action.DateConverter

 

类型转换与复杂属性配合使用

form 标签的 name 属性可以被映射到一个属性的属性. 

 



 

 

类型转换与Collection配合使用

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

 



 

 

 

 

 

  • 大小: 15.5 KB
  • 大小: 39.4 KB
  • 大小: 136.7 KB
  • 大小: 170.9 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics