struts2的深入学习(二)

来源:互联网 发布:珠宝标签打印软件 编辑:程序博客网 时间:2024/05/17 19:56

一、参数封装类型的转换

有时候我们会发现,页面把参数传输到后台,采用的都是字符串的传输。但是,后台接收的属性类型不是字符串,一般情况下,我们只需要在后台获得参数时进行变换即可,例如Integer类型可以通过Integer.parse(“”)就可以解决,但是也有特殊的情况,比如下面这个情况。

struts2默认情况下是可以解析“1990-01-01”类型的时间字符串,但是当前台传递“1990/01/01”时,此时就需要使用类型转换器来解决这个问题,大致的原理如下图
原理图

下面用一个例子来学习

声明一个User实体类,增加三个私有属性username、password、birthday,其中birthday是java.util.Date类,一个无参构造器,添加get/set方法

前台代码
regiser.jsp

struts.xml配置文件
struts.xml

RegisterAction代码
RegisterAction

使用类型转换器需要创建和注册这两个步骤

步骤一、创建自定义参数类型的转换器(两种方式)

方法一
可以实现com.opensymphony.xwork2.conversion.TypeConverter接口,进而实现其中convertValue方法(该方法需要传递6个参数,太麻烦,一般不使用这种方式)

方法二
声明MyConverter类继承StrutsTypeConverter类,该类实现了方法一的接口,进而实现了其中的convertValue方法
MyConverter

步骤二、在struts2中注册类型转换器

在需要转换的对象的同包下,创建一个属性映射文件(类名-conversion.properties)在这个文件中定义要转换这个model对象的哪个属性,并且指出用什么类去转换这个属性(属性=转换器类的全路径)
注册
开始测试,后台成功获得birthday属性

二、input结果视图

如果没有配置类型转换器,此时前台传递“1990/01/01”会发生什么?
异常
产生这个问题的原因是在Action标签中没有配置result=“input”这个视图。

这个问题如何产生的,先了解一下struts-default.xml文件
拦截器
interceptor是拦截器标签,其中name=“conversionError”是转换参数类型的拦截器,如果转换器在转换的过程中发生了错误,这个拦截器就会记录错误。而name=“workflow”的作用是,当程序运行到这个拦截器的时候,这个拦截器发现之前的拦截记录过异常信息,name这个拦截器就会停止对Action继续访问,终止请求,并且将请求转发到input结果视图。由于我没有配置input结果视图,所以报出上述异常。

解决方法

struts.xml文件中添加input结果视图,这个视图可以将错误信息返回到前台
struts.xml
在前台添加sturts的标签库,添加<s:fielderror/>标签,用于显示错误信息
register.jsp
此时测试,错误信息就会打印到前台
结果

但是当配置拦截器时,此时输入“1990-01-01”显然不符合要求,但是前台并没有在前台打印出错误信息,那是因为异常是发生在MyConverter类(即类型转换器)中,workflow拦截器没有发现异常。此时应该将MyConverter中的异常抛出
类型转换器
此时测试成功
注意:如果自定义的类型转换器在转换过程中出现异常,一定要向上抛出,否则,struts2没有办法捕获异常,页面就不会跳转到input视图

显示提示错误信息

虽然上面的方法提供了错误的信息,但是对一般的用户作用不大(看不懂英文^0^)

解决方法,在指定执行的Action同包下,创建Action的类名.properties文件。在这个文件中,显示发生错误字段的提示信息(invalid.fieldvalue.属性名=提示信息)
提示
此时前台打印我们定义的错误信息

三、使用struts2进行方法校验

由于ActionSupport这个类实现了Validateable这个接口,那么ActionSupport的子类就可以重写validate方法,在执行action中的业务方法的时候,首先会执行validate方法,所以可以使用validate()方法进行表单校验
validate方法
测试成功
但是这个方法也有一个缺点,就是当Action中有很多业务方法,那么在调用每一个方法的时候,都会先调用validate()方法

解决方法:可以声明一个方法名为(validate+需要校验的方法名)的方法,这个方法会单独校验指定的方法,注意若有validate方法也会调用,对于公共的参数可以编写在validate方法中
单独校验

思考:为什么servlet中的参数不能作为属性?那为什么struts2的Action就可以?
因为servlet在容器中只能被创建一次,而struts2会为每一个请求的访问都会单独的创建一个Action对象

这篇文章拖了很久,期间找了好久的工作,好累,好难,现在还是无业游民(飘飘然),写写博客放松一下

原创粉丝点击