2014-08-12|2077阅|作者:jun|举报 摘要:1.Action封装请求参数(重点)
2.struts2类型转换(了解)
3.struts2校验(次重点)
1.Action封装请求参数(重点)
2.struts2类型转换(了解)
3.struts2校验(次重点)
----------------------------------------------------------
1.Action封装请求参数
1.struts2是一个mvc框架,每一部分是什么?
view:jsp页面
ctrl: StrutsPrepareAndExecuteFilter+Action(一部分)
model:javaBean(Action)
Action是什么?
它可以完成ctrl功能,也可以完成model功能
2.Action怎样封装请求参数(三种)
1.直接在Action中声明参数(属性驱动)
就是将Action直接做为一个javaBean来处理.
优点:简单
缺点:需要单独在定义一个javaBean
问题:Action封装数据会不会存在线程安全问题?
不会,因为Action是多实例的,一次请求一个Action对象.
2.在Action中引入一个javaBean(属性驱动)
可以直接在Action中声明一个javaBean做为属性.
要求:在页面上必须使用ognl表达式来描述页面.
优点:数据直接封装到了javaBean。
缺点:页面上必须使用ognl表达式.
这种封装的原理: 谁来完成的参数封装
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
3.使用ModelDriven完成数据封装(模型驱动)---开发中应用比较多
步骤:
1.让Action实现ModelDriven
2.重写getModel()方法
3.在Action中实例化一个javaBean对象.
4.在getModel()方法中返回javaBean对象.
优点:页面不依赖于ognl
缺点:只能处理一个javaBean,而第二种方案可以处理多个javaBean
实例原理:
struts2 有很多围绕模型驱动的特性
* <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
为模型驱动提供了更多特性
---------------------------------------------------------------
请求参数封装到集合中(Collection Map)----了解
页面上:
<form action="${pageContext.request.contextPath}/login" method="post">
name1:<input type="text" name="list[0].username"><br>
name2:<input type="text" name="list[1].username"><br>
pwd1:<input type="password" name="list[0].password"><br>
pwd2:<input type="password" name="list[1].password"><br>
<hr>
name1:<input type="text" name="map['one'].username"><br>
name2:<input type="text" name="map['two'].username"><br>
pwd1:<input type="password" name="map['one'].password"><br>
pwd2:<input type="password" name="map['two'].password"><br>
<input type="submit" value="login">
</form>
Action中
private List<User> list;
private Map<String, User> map;
==================================================================================================
struts2中的类型转换
struts2提供了在大量的类型转换处理器.可以将请求参数直接转换成相应的类型封装到Action的javaBean中.
boolean 和 Boolean
char和 Character
int 和 Integer
long 和 Long
float 和 Float
double 和 Double
Date 可以接收 yyyy-MM-dd格式字符串
数组 可以将多个同名参数,转换到数组中
集合 支持将数据保存到 List 或者 Map 集合
报错:No result defined for action cn.itcast.action.ProductAction and result input
因为workflow拦截器发现了问题,要求跳转到input视图.
------------------------------------------------------------------
自定义类型转换器
struts2的所有类型转换器都是从 TypeConverter接口来的.
有三种方式:
1.创建一个类,实现TypeConverter接口.
重写方法参数太多
2.创建一个类去继承 DefaultTypeConverter
重写的方法参数简化,但功能没细化.
3.创建一个类去继承 StrutsTypeConverter
使用它,转为它将功能细化.
public abstract Object convertFromString(Map context, String[] values, Class toClass);
public abstract String convertToString(Map context, Object o);
步骤:
1创建一个类继承StrutsTypeConverter,重写方法
2.注册转换器
需要通过配置文件进行注册
1.针对于Action
配置文件名称 ActionName-conversion.properties
位置:与Action在一起
书写格式: 属性名=转换器类全名
2.针对于JaveBean
配置文件名称 javaBeanname-conversion.properties
位置:与javaBean 一起
书写格式: 属性名=转换器类全名
3.针对于全局
配置文件名称 xwork-conversion.properties
位置:src下(classpath路径下)
书写格式: 转换类型全名=转换器类全名
-------------------------------------------------------
问题:如果页面上提交的数据与自定义类型转换器,格式化不匹配,数据一样提交到了Action中,只是值为null.
这种情况是不正确的,数据如果转换错误了,不应该访问到Acion,而是跳转到input视图.
这就要求,在自定义的类型转换器中,如果发现类型转换错误,就需要抛出异常.
关于在input视图指定的页面上获取错误信息:
可以通过struts2提供的一个标签 <s:fielderror/>来显示错误信息
显示的信息 Invalid field value for field "createTime". 全是英文,我们可以对其进行国际化
1.创建一个properties文件 文件名字 ActionName.properties,位置放置在Action类所在包下.
2.在这个文件中可以定义
invalid.fieldvalue.属性名= 错误信息 (注意:如果在Action中使用了javaBean,不要包含属性的名称)
可以将错误信息以中文显示.
===========================================================================
模拟struts2流程与数据的封装
1.完成基本流程
Document document = reader
.read(new File(
"D:\\java0513\\workspace\\struts2_day021\\src\\mystruts.xml"));
if (document != null) {
// 是到根元素
Element root = document.getRootElement();
// 2.2得到指定名称的<Action>元素
String path = req.getRequestURI().substring(
req.getContextPath().length() + 1);
Element action = (Element) root
.selectSingleNode("//action[@name='" + path + "']");
if (action != null) {
// 2.3得到Action的class值.
String className = action.attributeValue("class"); // 得到类名
String methodName = action.attributeValue("method"); // 得到方法名
Class clazz = Class.forName(className);
Method m = clazz.getDeclaredMethod(methodName);
// 2.4调用m方法
String returnvalue = (String) m.invoke(clazz.newInstance());
// 2.5通过returnvalue与Action元素的子元素 result的name属性值对象.
Element result = (Element) action
.selectSingleNode("//result[@name='" + returnvalue
+ "']");
String skipPath = result.getText();
// 默认是请求转发.
req.getRequestDispatcher(skipPath).forward(req, resp);
return;
}
}
2.数据封装
1.属性驱动
Object bean=clazz.newInstance(); //这个是Action对象,也是一个javaBean
//封装数据到javaBean
BeanUtils.populate(bean, req.getParameterMap());
2.模型驱动
// 模型驱动
ModelDriven obj = (ModelDriven) bean;
Object b = obj.getModel();
==========================================================================================
struts2请求参数校验(服务器端)
分为两种
1.手动校验
2.自动校验
------------------------------------
1.手动校验(了解)
前提:要求Action类要继承自ActionSupport。
为什么要继承它?
因为ActionSupport类实现了Validateable这个接口,而我们做校验操作的方法就是这个接口下的validate方法.
步骤:
1.让Action继承自ActionSupport
2.重定validate方法
3.在validate方法中对数据进行校验.
4.在struts.xml文件中通过配置input进行页面跳转.在页面上通过<s:fielderror/>来展示错误信息.
问题:
在一个action中有多个业务方法,例如: add update select,只需要对add,update,进行校验,而select不做校验.
怎样可以对Action中指定方法进行校验?
* validate方法会对Action中所有业务方法进行校验,如果只想校验某一个方法 : validate方法名()
例如要对add方法校验,只需要创建一个 validateAdd方法就可以.
-----------------------------------------------------------------------
2.自动校验(重点)
使用struts2 提供的校验框架
1.xml配置校验
2.annotation校验(不讲)
------------------------------------------
xml校验
1.编写jsp页面 regist.jsp
2.编写Action继承自ActionSupport或实现Validateable接口
3.编写校验规则(xml)
1.在Action所在的包下创建一个xml文件,文件的名称是 Action名称-validation.xml。
2.给这个xml文件添加约束
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
</validators>
3.编写校验规则
<field name="username"> name值代表要对哪一个属性进行校验
<field-validator type=""> type值是指定校验器
<message>用户名不能为空</message> 是错误信息
</field-validator>
</field>
4.关于校验器
xwork-core-2.3.7.jar 中 /com/opensymphony/xwork2/validator/validators/default.xml
定义
<validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
<validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
<validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
<validator name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
<validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
<validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
<validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
<validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
<validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
<validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
<validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
<validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
<validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
<validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
<validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
<validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
内建校验器
* required (必填校验器,要求被校验的属性值不能为null)
* requiredstring (必填字符串校验器,要求被校验的属性值不能为null,并且长度大于0,默认情况下会对字符串去前后空格)
* stringlength (字符串长度校验器,要求被校验的属性值必须在指定的范围内,否则校验失败,minLength参数指定最小长度,maxLength参数指定最大长度,trim参数指定校验field之前是否去除字符串前后的空格)
* regex (正则表达式校验器,检查被校验的属性值是否匹配一个正则表达式,expression参数指定正则表达式,caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认值为true)
* int(整数校验器,要求field的整数值必须在指定范围内,min指定最小值,max指定最大值)
* double(双精度浮点数校验器,要求field的双精度浮点数必须在指定范围内,min指定最小值,max指定最大值)
* fieldexpression (字段OGNL表达式校验器,要求field满足一个ognl表达式,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过)
* email(邮件地址校验器,要求如果被校验的属性值非空,则必须是合法的邮件地址)
* url(网址校验器,要求如果被校验的属性值非空,则必须是合法的url地址)
* date(日期校验器,要求field的日期值必须在指定范围内,min指定最小值,max指定最大值)
案例
required 必填校验器
<field-validator type="required">
<message>性别不能为空!</message>
</field-validator>
requiredstring 必填字符串校验器
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>用户名不能为空!</message>
</field-validator>
stringlength:字符串长度校验器
<field-validator type="stringlength">
<param name="maxLength">10</param>
<param name="minLength">2</param>
<param name="trim">true</param>
<message><![CDATA[产品名称应在2-10个字符之间]]></message>
</field-validator>
int:整数校验器
<field-validator type="int">
<param name="min">1</param>
<param name="max">150</param>
<message>年龄必须在1-150之间</message>
</field-validator>
date: 日期校验器
<field-validator type="date">
<param name="min">1900-01-01</param>
<param name="max">2050-02-21</param>
<message>生日必须在${min}到${max}之间</message>
</field-validator>
url: 网络路径校验器
<field-validator type="url">
<message>传智播客的主页地址必须是一个有效网址</message>
</field-validator>
email:邮件地址校验器
<field-validator type="email">
<message>电子邮件地址无效</message>
</field-validator>
regex:正则表达式校验器
<field-validator type="regex">
<param name="regexExpression"><![CDATA[^13\d{9}$]]></param>
<message>手机号格式不正确!</message>
</field-validator>
fieldexpression : 字段表达式校验
<field-validator type="fieldexpression">
<param name="expression"><![CDATA[(password==repassword)]]></param>
<message>两次密码输入不一致</message>
</field-validator>
------------------------------------------------------------------------------------
使用自动校验操作(xml方式)怎样可以对指定的Action操作进行校验?
只需要在给xml文件起名时,添加上指定的action的name值就可以。
例如:
<action name="user_*" class="cn.itcast.action.RegistAction" method="{1}">
<result>/success.jsp</result>
<result name="input">/regist.jsp</result>
</action>
RegistAction-user_regist-validation.xml 这时它是对 user_regist请求进行校验
如果访问的是 user_add是不会进行校验的。