Struts框架使用Action作为业务处理模型
Action的特点:
可以是任何一个POJO类
与Servlet API无关
Action的生命周期
客户端发起请求,产生Action实例
执行业务处理
处理完Action存入valueStack
客户端发起下一次相同请求时,之前的Action销毁,,重新产生新的Action实例。
Action必须实现execute方法
execute方法的返回值决定了struts.xml中Action的result的name值
<result name="success">/WEB-INF/success.jsp</result>
Struts2提供的Action创建方式
实现Action接口
继承ActionSupport类
Action接口
内置execute方法
定义了SUCCESS、INPUT、LOGIN、NONE、ERROR等常量
ActionSupport类
实现了Action,ValidtionAware等接口
国际化信息
数据校验
获取request、session等常用对象
Action的非侵入式设计无法直接获取request、session等对象
(1)ActionContext获取
getContext获取request模拟实例
getSession获取session模拟实例
getApplication获取servletContext模拟实例
(2)ServletActionContext (直接访问Servlet API)
getRequest获取request实例
getServletContext获取实例
驱动的两种方式
属性驱动:传统的表单数据直接多为Action属性写入(第一章最后一个知识点)
模型驱动:使用单独的model实例封装表单数据
模型驱动
实现方式:(1)将表单封装成实体类(Model)
(2)Action添加Model属性并提供setter和getter方法
(3)实现ModelDriven接口
(4)ModelDriven中的getModel方法返回封装的Model实例
表单数据封装Model,Model的属性名要和表单的属性一致
UserModel.java
public class UserModel{
private String userName;
private String password;
public UserModel(){}
public UserModel(String userName, String password){
super(userName, password);
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
public class RegistAction extends ActionSupport implements ModelDriven<UserModel> {
private UserModel model;
@Override
public String execute() throws Exception {
System.out.println(model.getUserName());
System.out.println(model.getPassword());
return SUCCESS;
}
/**
* 返回表单模型的实例
*/
public UserModel getModel() {
//实例化表单模型
model = new UserModel();
return model;
}
public void setModel(UserModel model) {
this.model = model;
}
- }
result
<action name="login" class="com.niit.action.LoginAction">
<!-- 配置视图 -->
<result name="success">/WEB-INF/success.jsp</result>
<result name="error">/index.jsp</result>
</action>
在Struts配置文件中,Action通过配置result关联模型和视图。
result可以通过设置type属性来决定跳转方式
result的type类型有
(
默认) Dispather 跳转JSP或Servlet
Chain 跳转至其他Action
Redirect 重定向URL
Redirect-action 以重定向的方式跳转到其他Action
result的name属性默认值为success
对于跳转相同的字符串mapping可以
在package中设置全局result
<!-- 配置全局result -->
<global-results>
<result name="exception">/WEB-INF/error.jsp</result>
</global-results>
注意点:
(1)如果Action没有配置result则在global-result中查找
(2)如果Action中存在与global-result相同的name,则优先调用局部的result
对于一个表单页面有多个按钮提交数据的解决
通过
动态方法来解决
Struts提供了DMI解决同一表单不同提交的问题
DMI(Dynamic Method Invocation)
动态方法的使用步骤
(1)Action中定义多个方法
(2)配置Action指定method属性(
method必须要和Action的方法名相同)
/**
* 动态方法,将多个业务方法合并在一个Action中处理
* @author Administrator
*
*/
public class DMI_Action extends ActionSupport{
/**
* 处理登录的业务方法
* @return
*/
public String login(){
System.out.println("do Login!");
return SUCCESS;
}
/**
* 处理注册的业务方法
* @return
*/
public String regist(){
System.out.println("do Regist!");
return SUCCESS;
}
}
<!-- DMI动态方法的配置,method必须和Action中的方法名相同-->
<action name="DMI_login" class="com.niit.action.DMI_Action" method="login">
<result name="success">WEB-INF/result.jsp</result>
</action>
<action name="DMI_regist" class="com.niit.action.DMI_Action" method="regist">
</action>
异常处理
exception-mapping用来捕获Action中的异常
result表示对应result的name值
exception表示要捕获的异常类型
<action name="regist" class="com.niit.action.RegistAction">
<!-- 配置异常处理 -->
<exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
<result name="success">/WEB-INF/success.jsp</result>
<!-- 配置异常处理后跳转的视图 -->
<result name="error">/WEB-INF/error.jsp</result>
</action>
可以配置全局异常处理
<package name="niit" extends="struts-default" namespace="/user">
<!-- 配置全局result -->
<global-results>
<result name="exception">/WEB-INF/error.jsp</result>
</global-results>
<!-- 配置全局异常处理,一般会结合global-results使用 -->
<global-exception-mappings>
<exception-mapping result="exception" exception="java.lang.Exception"></exception-mapping>
</global-exception-mappings>
</package>
类型转换
客户端请求中所有数据都写入request对象,request对象封装的数据都为String类型。
而表单模型中的数据可能为Date类型,实体对象类型。。。。。。
有效的数据类型可以增强系统的安全性,阻止非法数据的侵入。
类型转换器:
用于将请求中的数据根据Action中指定的数据类型进行转换
类型转化器的分类:
Struts內建转换器:主要针对基本数据类型进行类型转换
自定义转换器:Action中出现数组,集合,对象就需要自定义类型转换器
编写的转换器继承ognl.DefaultTypeConverter,也
继承StrutsTypeConverter
StrutsTypeConverter继承了DefaultTypeConverter类,更便于进行操作,提供了字符至对象,对象至字符的双向转换。
继承DefaultTypeConverter 即重写convertValue方法
import ognl.DefaultTypeConverter;
public class ResigtConverter extends DefaultTypeConverter {
@Override
public Object convertValue(Map context, Object target, Member member,
String propertyName, Object value, Class toType) {
// TODO Auto-generated method stub
return super.convertValue(context, target, member, propertyName, value, toType);
}
}
StrutsTypeConverter的相关逻辑也差不多
public class LoginConverter extends StrutsTypeConverter {
@Override
public Object convertFromString(Map context, String[] values, Class arg2) {
User user = new User();
user.setUserName(values[0]);
user.setPassword(values[1]);
System.out.println("转换器中:"+user.getUserName());
return user;
}
@Override
public String convertToString(Map arg0, Object arg1) {
// TODO Auto-generated method stub
return null;
}
}
String[] values字符串数组封装了所有提交的数据,且文本框的值始终存在,不填则为空字符串。
自定义类型转换器的实现步骤:
(1)编写转换器 继承StrutsTypeConveter
(2)编写ActionName-conversion.properties,该配置文件在对应action所在包路径下
如:LoginAction-conversion.properties
user=com.niit.convert.LoginConverter
(3)页面中传递的表单元素那么应为表单模型的属性名 private UserModel user;
<form action="user/login.action" method="post">
userName:<input type="text" id="userName" name="user">
password:<input type="password" name="user"><br/>
<input type="submit" value="login">
</form>
(4)action中配置result name=“input”
转换器中出现的异常,由拦截器对异常进行处理,并封装在valueStack中。
在转换器出现异常时,action会跳转至result的name属性值为input的视图中。
全局转化器
全局转换器可以在整个项目中转换对应的数据
使用步骤:
(1)编写转换器类
(2)编写xwork-conversion.properties文件至classpath路径下
com.niit.model.UserModel=com.niit.convert.Myconversion
OGNL转换器
基于struts的OGNL引擎自动完成类型转换
只需要在页面中将name值设定为Action模型.属性
<form action="user/login.action" method="post">
userName:<input type="text" id="userName" name="user.userName">
password:<input type="password" name="user.password"><br/>
<input type="submit" value="login">
</form>
未处理异常将会导致action执行中断
页面无法正确呈现数据
struts已经帮我们做了异常处理,只是我们没有进行页面跳转的配置及呈现异常
异常处理机制
通过conversionError拦截器处理异常
错误信息写入contextStack中
查找并访问当前Action的input-result,根据input-result跳转页面
<s:filedError>标签呈现错误信息