类型转换
1、默认转换
日期的处理
使用<s:date format=”yyyy-MM-dd HH:mm:ss” name=”date”>标签,具体见文档
Struts2有对应的拦截器已经做了一些默认的转换
参数传递转换:
简单类型转换 test?name=a&age=2 日期类型 test?date=1988-08-08 List类型 List<String> interests test?interests=math&interests=English Set类型 Set<String> interests test?interests=math&interests=English Map类型 Map<String, String> users test?users[‘a’]=usera&users[‘b’]=userb
2、自定义类型转换器
Locale文本输入框对应是Action中的类型为java.util.Locale的属性loc,
所以需要创建一个自定义转变器实现两者间的转换。
所有的Struts 2中的转换器都必须实现ognl.TypeConverter接口 。
为了简单起见,OGNL包也为你提供了ognl.DefaultTypeConverter类去帮助您实现转换器。
在例子中,LocaleConverter继承了ognl.DefaultTypeConverter,
重载了其方法原型为“public Object convertValue(Map context, Object value, Class toType) ”的方法。
下面简单地介绍一下函数的参数:
context——用于获取当前的ActionContext
value——需要转换的值
toType——需要转换成的目标类型
当然也可以更简单的实现StrutsTypeConverter ,只需要重写convertFromString 、convertToString 方法。
实现转换器,我们需要通过配置告诉Struts 2。我们可以通过以下两种方法做到这点:
1.配置全局的类型转换器,也即是上例的做法——在源代码文件夹下,新建一个名为“xwork-conversion.properties”的
配置文件,并在文件中加入“待转换的类型的全名(包括包路径和类名)=转换器类的全名”对;
2.应用于某个特定类的类型转换器,做法为在该类的包中添加一个格式为“类名-conversion.properties”的配置文件 ,并
在文件中加入“待转换的属性的名字=转换器类的全名”对。上面的例子也可以这样配置——在源代码文件夹的tutorial包
下新建名为“HelloWorld-conversion.properties”文件,并在其中加入“java.util.Locale =
tutorial.LocaleConverter”。
3、已有的转换器
对于一此经常用到的转换器,如日期、整数或浮点数等类型,Struts 2.0已经为您实现了。下面列出已经实现的转换器。
预定义类型,例如int、boolean、double等;
日期类型 ,使用当前区域(Locale)的短格式转换 ,即DateFormat.getInstance(DateFormat.SHORT);
集合(Collection)类型, 将request.getParameterValues(String arg)返回的字符串数据与java.util.Collection转换;
集合(Set)类型 , 与List的转换相似,去掉相同的值;
数组(Array)类型 , 将字符串数组的每一个元素转换成特定的类型,并组成一个数组。
对于已有的转换器,大家不必再去重新发明轮子。Struts在遇到这些类型时,会自动去调用相应的转换器。
4、转换错误处理
不知道大家在运行上面的例子时,有没有填错日期或数字情况,又或者您有没有思考过这种情况?
如果还没有尝试的朋友可以试一下,在第一行的Price和 Date of production中输入英文字母,然后按“Submit”提交。
你会看到页面为空白,再看一下服务器的控制台输出,
有如下语句:
警告: No result defined for action tutorial.ProductConfirm and result input,
它提示我们没有为Action定义输入结果,
所以,我们应该在源代码文件夹下的struts.xml中的ProductConfirm Action 中加入以下代码:
<result name="input">/AddProducts.jsp</result>
重新加载应用程序,刷新浏览器重新提交请求,这时页面返回AddProducts.jsp,格式错误的输入框的值被保留,
如下图所示:
图 没有提示的错返回页面
当然,我们还可以在页面上加上错误提示信息,通过在AddProducts.jsp的“<body>”后,加入下面代码可以实现:
<div style="color:red"> <s:fielderror /> </div>
刷新浏览器,重新提交请求,出现如图所示页面:
图 带提示的错返回页面
Struts 2.0里的一个名为conversionError的拦截器(interceptor)工作,它被注册到默认拦截器栈(default interceptor stack)中。
Struts 2.0在转换出错后,会将错误放到ActionContext中,在conversionError的作用是将这些错误封装为对应的项错误(field error),因此我们可以通过<s:fielderror />来将其在页面上显示出来。另外,大家看第二和第三行的Price都被赋为0.0的值,而第一行则保留其错误值。这同样是conversionError的功劳——没有出错的行调用的products[index].price(默认值为0.0),而出错的行则会被赋为页面所提交的错误值,这样可以提供更好的用户体验。
如:
<action name="test" class="com.bjsxt.action.TestAction"> <result>/test.jsp</result> <result name="input">/test.jsp</result> </action>
表示当转换失败转到test.jsp页面
总结:
a) 默认转换
i. 日期处理
b) 写自己的转换器:
public class MyPointConverter extends DefaultTypeConverter{ @Override public Object convertValue(Object value, Class toType) { if(toType == Point.class) { Point p = new Point(); String[] strs = (String[])value; String[] xy = strs[0].split(","); p.x = Integer.parseInt(xy[0]); p.y = Integer.parseInt(xy[1]); return p; } if(toType == String.class) { return value.toString(); } return super.convertValue(value, toType); } } public class MyPointConverter extends StrutsTypeConverter{ @Override public Object convertFromString(Map context, String[] values, Class toClass) { Point p = new Point(); String[] strs = (String[])values; String[] xy = strs[0].split(","); p.x = Integer.parseInt(xy[0]); p.y = Integer.parseInt(xy[1]); return p; } @Override public String convertToString(Map context, Object o) { // TODO Auto-generated method stub return o.toString(); } }
c) 三种注册方式:
i. 局部:XXXAction-conversion.properties
1. p(属性名称) = converter
ii. 全局:xwork-conversion.properties
1. com.xxx.XXX(类名)= converter
iii. Annotation
d) 如果遇到非常麻烦的映射转换
i. request.setAttribute();
ii. session
剩下部分内容 :
1. Lambda表达式
2. 验证框架
3. UI标签
4. 类型转换中的异常处理
5. 上传与下载文件
6. Struts2注解