从一个 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 里的对象, 这常见于需要快速录入批量数据的场合
相关推荐
本案例"Struts2之类型转换器的使用案例struts002"深入探讨了如何自定义类型转换器以及在实际应用中的使用。 首先,Struts2框架提供了一系列内置的类型转换器,可以自动处理基本类型和常见类型的数据转换,如String...
这篇博客“Struts2数据类型转换器”可能深入探讨了这个主题,虽然具体的细节无法在此给出,但我们可以根据Struts2中数据类型转换的工作原理来展开讨论。 在Java Web开发中,用户通过表单提交的数据通常是字符串形式...
总之,Struts2的类型转换机制是其强大功能之一,它简化了数据绑定过程,使得开发者能够专注于业务逻辑,而不是数据转换的细节。理解并熟练掌握Struts2的类型转换,将有助于提高开发效率和代码质量。在实际项目中,应...
这个过程涉及到了类型转换,Struts2内置了一套转换器机制,能够自动处理基本类型和一些常见类型的转换。然而,对于如Date这样的复杂类型,需要自定义转换器来处理。 创建自定义类型转换器的步骤如下: 1. **定义...
在Struts2中,类型转换器(Type Converter)是框架的一个关键特性,用于处理Action类中属性的自动类型转换。这个特性使得开发者无需手动进行数据类型之间的转换,从而提高了开发效率和代码的可读性。 标题中的...
Struts2是一个强大的MVC框架,它在处理用户请求时提供了丰富的功能,其中包括类型转换(Converter)。类型转换是Struts2框架中一个重要的特性,它允许我们把前端表单提交的数据自动转换为后端Java对象的属性。在这个...
在这个"struts2简单实例(类型转换)"中,我们将探讨Struts2如何处理不同类型的数据转换,以及如何创建一个简单的演示应用。 首先,让我们理解什么是类型转换。在Web应用程序中,用户通过表单提交的数据通常是字符...
Struts2是一个流行的Java web开发框架,其核心是Action,而类型转换是Struts2处理用户输入数据的一个重要环节。Struts2内置了多种类型转换,可以将HTTP请求中的字符串数据转换为各种基本类型和复杂类型,如日期、...
### Struts2自定义类型转换:深入解析与实践 #### 引言 在Web开发中,数据类型转换是一项常见的需求,特别是在用户输入的数据与后端处理的数据类型不一致时。Struts2框架提供了强大的类型转换机制,允许开发者...
本练习主要关注如何在Struts2中实现自定义的数据类型转换,以满足特定业务需求。 首先,我们需要了解Struts2的数据转换机制。当用户提交表单数据时,Struts2会通过ActionContext获取到这些数据,并尝试将其转换为...
### Struts2 数据类型转换详解 #### 一、引言 在Web开发中,特别是使用Struts2框架进行开发时,数据类型转换是一项至关重要的功能。由于Web应用程序的基础通信协议HTTP仅支持字符串形式的数据传输,因此,服务器端...
SSH之Struts2数据类型转换国际化及文件上传下载
在Struts2中,类型转换和国际化是两个重要的特性,用于处理数据类型之间的转换以及多语言环境下的内容显示。 **类型转换**是Struts2处理请求参数与Action类属性之间数据类型不匹配的过程。当用户通过表单提交请求时...
Struts2是一个强大的MVC框架,它在处理Web应用程序时提供了许多便利,其中包括类型转换功能。类型转换是将用户输入的数据自动转化为服务器端处理所需的类型,这样可以避免手动转换带来的繁琐工作。本篇文章将深入...
在处理用户输入时,Struts2框架需要将请求参数转换为对应的Java对象属性,这个过程就涉及到类型转换。然而,当用户输入的数据格式不正确时,就会出现类型转换错误,例如在尝试将字符串转换为日期时。本篇文章将深入...
struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换struts2学习笔记3数据类型转换
struts2.1数据类型转换2struts2.1数据类型转换2struts2.1数据类型转换2struts2.1数据类型转换2struts2.1数据类型转换2struts2.1数据类型转换2struts2.1数据类型转换2struts2.1数据类型转换2
在Struts2框架中,自定义类型转换器是开发者为了满足特定需求,对框架默认的类型转换机制进行扩展的一种方式。Struts2允许我们创建自己的转换器类来处理输入数据,确保模型对象的属性能够正确地被转换为预期的数据...