1 封装请求参数
1.1 属性封装
只要在Action中提供与参数对应的set方法即可自动封装
1.2 自动类型转换
struts会自动转换8大基本数据类型和对应包装类.以及Date类型
其中date类型对数据提交格式有要求: yyyy-MM-dd
1.3 容器数据封装
容器:数组、List、Set、Map等
1.3.1 jsp表单
<form action="${pageContext.request.contextPath}/demo2Action" method="post">
Map<br/>
<input type="text" name="userMap['u001'].userName"/> <br/>
<input type="text" name="userMap['u001'].userPwd"/> <br/>
<input type="text" name="userMap['u002'].userName"/> <br/>
<input type="text" name="userMap['u002'].userPwd"/> <br/>
List<br/>
<input type="text" name="userList[0].userName"/> <br/>
<input type="text" name="userList[0].userPwd"/> <br/>
<input type="text" name="userList[1].userName"/> <br/>
<input type="text" name="userList[1].userPwd"/> <br/>
Array<br/>
<%-- request.getParameterValues("username") --%>
<input type="checkbox" name="hobby" value="抽烟"/>
<input type="checkbox" name="hobby" value="喝酒"/>
<input type="checkbox" name="hobby" value="烫头"/> <br/>
<input type="submit" value="提交"/>
</form>
1.3.2 action类
public class Demo2Action extends ActionSupport {
//封装到Map ,必须提供getter,所有封装需要使用同一个Map对象
private Map<String,User> userMap;
public void setUserMap(Map<String, User> userMap) {
this.userMap = userMap;
}
public Map<String, User> getUserMap() {
return userMap;
}
//封装到List,必须提供getter,,所有封装需要使用同一个List对象
// * List<User> 和 User[] 等效的
private List<User> userList;
public void setUserList(List<User> userList) {
this.userList = userList;
}
public List<User> getUserList() {
return userList;
}
//数组,不需要提供getter,直接一次性封装数据,使用String[] request.getParameterValues("hobby")
private String[] hobby;
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
@Override
public String execute() throws Exception {
System.out.println(userMap);
System.out.println(userList);
System.out.println(hobby);
System.out.println(Arrays.toString(hobby));
return "none";
}
}
2 类型转换
2.1 默认支持类型转换
字符串 <–> 指定类型 之间转换
字符串 转成 指定类型:表单提交,浏览器发送服务器
指定类型 转成 字符串:标签回显,服务器发送浏览器
指定类型
8个基本类型、以及包装类
时间 Date,字符串有格式要求:yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss
数组、List、Map
2.2 自定义类型转换器
2.2.1 实现类
方案1:实现接口:TypeConverter,有一个方法,但参数过多。
方法2:继承默认实现类:DefaultTypeConverter 。提供简洁方法convertValue(Object , Class)
![在这里插入图片描述](https://img-blog.csdnimg.cn/09f01387ef1e438a877484fedfdf528e.png)
convertValue(Object value , Class toType)
#1 表单提交,浏览器发送到服务器。浏览器发送的肯定字符串String,需要转换成指定的类型。例如Date类型
参数1:value,表示浏览器发送的数据。类型是String[] ,底层使用request.getParameterValues("...")
参数2:toType,表示需要转换的类型,java.uilt.Date类型
** 操作
// 如果toType是 Date类型,表示希望将 字符串转成 时间
if(toType == java.util.Date.class){
//获得数据
String[] params = (String[])value;
//转成成时间
}
#2 标签回显,服务器发送 浏览器,类型之前已经从字符串转成时间,现在希望将时间再转换成 字符串。
参数1:value,表示服务器已经转成好的时间。类型Date。
参数2:toType,表示需要转换的类型,String类型
** 操作
if(toType == String.class){
// 将数据强转时间
Date date = (Date)value;
// 格式化
}
2.2.2 执行流程
2.2.3 注册转换器
2.2.3.1 介绍
局部转换器:只对当前Action类有效。
限制:
只能对action类的属性进行转化,不能对javabean中属性转换
全局转换器:对所有的Action类有效。
注意:自定义转换器很少使用,一般情况使用默认就可以。多读
2.2.3.2 局部
位置:action类同包
名称:actionClass-conversion.properties
actionClass : action类的类名
conversion.perperties :固定值
内容:属性=转换器
2.2.3.3 全局
位置:src
名称:xwork-conversion.properties
内容:需要转换的类=转换器
2.2.3.4 转换实现
public Object convertValue(Object value, Class toType) {
try {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
//1 浏览器发送服务器--表单提交
// * value : String[]
// * toType : Date
if (toType == java.util.Date.class) {
// 1.1 强转,获得数据
String[] paramValues = (String[]) value;
// 1.2 转成时间,返回 , 默认使用第一个
return dateFormat.parse(paramValues[0]);
}
//2 服务器发送浏览器--标签回显
// * value : 服务器已经转换好的数据 Date
// * toType : 需要类型 String
if(toType == String.class){
// 获得时间数据
java.util.Date date = (java.util.Date)value;
// 格式化
return dateFormat.format(date);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
//执行其他
return null;
}
3 数据校验
3.1 校验分类
浏览器端校验:JavaScript,但不安全
服务器端校验:struts校验
3.2 struts校验介绍
手动校验:编写代码
适用于需要与数据库交互。
xml校验:编写配置文件
通用校验,逻辑简单。例如:不能为空,长度10,是否相等。
3.3 手动校验
如果需要手动校验,必须实现接口:Validateable,提供一个方法 validate()
action所有方法校验
实现接口,并实现方法validate()
action单个方法校验
实现接口,并编写方法 validate方法() , 此处“方法”表示执行的方法名称,首字母大写。
例如:add() 执行前需要校验,必须编写 validateAdd()
注意:先执行“单个方法”校验,再执行“所有方法”校验
提供错误提示,阻止目标方法的执行
this.addFieldError(“”, “”) 给指定的字段设置提示信息
<s:fielderror>jsp显示错误
this.addActionMessage(aMessage) action提示提示信息
<s:actionmessage/>jsp显示错误
this.addActionError(anErrorMessage) action错误
<s:actionerror/>jsp显示错误
3.4 xml校验
单个方法校验
位置:action类同包
名称:actionClass-actionName-validation.xml
actionClass :表示action类名
actionName:表示action访问名称,及
validation.xml :固定后缀
内容:xml必须提供约束(DTD、schema[命名空间])
dtd文件位置:xwork-core-2.3.15.3.jar!/xwork-validator-1.0.3.dtd
dtd文件内容:
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
所有方法校验
位置:action类同包
名称:actionClass-validation.xml,解释同上
内容:同上
struts提供的校验器
校验配置文件位置:xwork-core-2.3.15.3.jar!/com/opensymphony/xwork2/validator/validators/default.xml
4 拦截器
4.1 介绍
struts提供拦截器,对action类进行增强的。struts已经实现多个拦截器,完成不同的功能。
例如:文件上传、数据校验、类型转换、参数封装等
4.2 默认拦截者栈
struts-default.xml 提供struts完成所有拦截器,也提供默认拦截器栈
所有的action默认使用那个拦截器栈
声明一个拦截器栈,名称为“defaultStack”,通常称为:默认拦截器栈
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="debugging"/>
</interceptor-stack>
servletConfig : 用于给action类注入Servlet api。
例如:action类实现ServletRequestAware就可以被struts框架注入HttpServletRequest对象
modelDriven: 调用action类的getModel()方法,获得javabean实例,如果没为null,将交予struts。
fileUpload:struts默认支持文件上传。
params:给action类进行数据封装。如果使用ModelDriven,就给javabean封装数据。
conversionError:将转换错误添加到action类的错误提示信息中。
将执行 action.addFieldError(“属性”,“错误提示”);
validation:将执行action所有校验。先执行注解校验,再执行单个方法校验,最后所有方法的校验
workflow :从action类获得添加的错误信息,如果没有发行。如果有返回“input”
方式1:默认情况,如果存在错误,返回值“input”
方式2:实现接口ValidationWorkflowAware,修改整个action的错误返回结果集名称,将执行方法 getInputResultName()
方式3:通过@InputConfig注解,给指定的方法配置出现错误时,返回结果result的名称。
public class Demo8Action extends ActionSupport implements ValidationWorkflowAware{
@Override
public String getInputResultName() {
return "xxx"; //出现错误不再返回input,二是xxx,所有的方法都使用。
}
@Override
public String execute() throws Exception {
System.out.println(this.getText("usernameMsg"));
System.out.println(this.getText("passwordMsg"));
System.out.println(this.getText("company"));
return NONE;
}
@InputConfig(resultName="loginInput") //如果登录出现异常,将返回不是input,而是loginInput
public String login(){
return SUCCESS;
}
@InputConfig(resultName="registerInput") //如果注册出现异常,将返回不是input,而是registerInput
public String register(){
return SUCCESS;
}
}
4.3 自定义拦截器
实现接口:com.opensymphony.xwork2.interceptor.Interceptor
//初始化方法
public void init() { }
//拦截方法
public abstract String intercept(ActionInvocation invocation) throws Exception;
invocation.getAction() 获得当前action类实例
invacation.invoke() 放行
//销毁方法
public void destroy() { }
继承父类:com.opensymphony.xwork2.interceptor.MethodFilterInterceptor
在使用自定义拦截器,可以对指定的方法进行操作(哪些方法不拦截,哪些必须拦截)
设置属性includeMethods,确定哪些方法进行拦截
设置属性excludeMethods,确定哪些方法不进行拦截
将指定的拦截器,声明成默认的。
注意:如果使用自定义xxx,“defaultStack”将被覆盖。
注意:拦截器只拦截action类,不拦截jsp文件。