(2)Struts2-Struts的业务模型

Struts框架使用Action作为业务处理模型
Action的特点:
    可以是任何一个POJO类
    与Servlet API无关

Action的生命周期
    客户端发起请求,产生Action实例
    执行业务处理
    处理完Action存入valueStack
    客户端发起下一次相同请求时,之前的Action销毁,,重新产生新的Action实例。

Action必须实现execute方法
execute方法的返回值决定了struts.xml中Action的result的name值
   
   
  1. <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获取实例


Struts的Action(模型对象)负责业务处理同时也会负责封装请求中的数据。
驱动的两种方式
    属性驱动:传统的表单数据直接多为Action属性写入(第一章最后一个知识点)
    模型驱动:使用单独的model实例封装表单数据


模型驱动
        实现方式:(1)将表单封装成实体类(Model)
                           (2)Action添加Model属性并提供setter和getter方法
                           (3)实现ModelDriven接口
                           (4)ModelDriven中的getModel方法返回封装的Model实例
表单数据封装Model,Model的属性名要和表单的属性一致
            UserModel.java
   
   
  1. public class UserModel{
  2. private String userName;
  3. private String password;
  4. public UserModel(){}
  5. public UserModel(String userName, String password){
  6. super(userName, password);
  7. }
  8. public String getUserName() {
  9. return userName;
  10. }
  11. public void setUserName(String userName) {
  12. this.userName = userName;
  13. }
  14. public String getPassword() {
  15. return password;
  16. }
  17. public void setPassword(String password) {
  18. this.password = password;
  19. }
  20. }
    
    
  1. public class RegistAction extends ActionSupport implements ModelDriven<UserModel> {
  2. private UserModel model;
  3. @Override
  4. public String execute() throws Exception {
  5. System.out.println(model.getUserName());
  6. System.out.println(model.getPassword());
  7. return SUCCESS;
  8. }
  9. /**
  10. * 返回表单模型的实例
  11. */
  12. public UserModel getModel() {
  13. //实例化表单模型
  14. model = new UserModel();
  15. return model;
  16. }
  17. public void setModel(UserModel model) {
  18. this.model = model;
  19. }
  20. }



result
    
    
  1. <action name="login" class="com.niit.action.LoginAction">
  2. <!-- 配置视图 -->
  3. <result name="success">/WEB-INF/success.jsp</result>
  4. <result name="error">/index.jsp</result>
  5. </action>
   在Struts配置文件中,Action通过配置result关联模型和视图。

result可以通过设置type属性来决定跳转方式
result的type类型有
默认) Dispather        跳转JSP或Servlet
                Chain              跳转至其他Action
                Redirect          重定向URL
                Redirect-action        以重定向的方式跳转到其他Action

result的name属性默认值为success

对于跳转相同的字符串mapping可以
                在package中设置全局result
    
    
  1. <!-- 配置全局result -->
  2. <global-results>
  3. <result name="exception">/WEB-INF/error.jsp</result>
  4. </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的方法名相同
    
    
  1. /**
  2. * 动态方法,将多个业务方法合并在一个Action中处理
  3. * @author Administrator
  4. *
  5. */
  6. public class DMI_Action extends ActionSupport{
  7. /**
  8. * 处理登录的业务方法
  9. * @return
  10. */
  11. public String login(){
  12. System.out.println("do Login!");
  13. return SUCCESS;
  14. }
  15. /**
  16. * 处理注册的业务方法
  17. * @return
  18. */
  19. public String regist(){
  20. System.out.println("do Regist!");
  21. return SUCCESS;
  22. }
  23. }
     
     
  1. <!-- DMI动态方法的配置,method必须和Action中的方法名相同-->
  2. <action name="DMI_login" class="com.niit.action.DMI_Action" method="login">
  3. <result name="success">WEB-INF/result.jsp</result>
  4. </action>
  5. <action name="DMI_regist" class="com.niit.action.DMI_Action" method="regist">
  6. </action>



异常处理
Struts通过AOP设计,允许将异常与业务处理剥离开来,降低程序的耦合性。
       exception-mapping用来捕获Action中的异常
       result表示对应result的name值
       exception表示要捕获的异常类型
    
    
  1. <action name="regist" class="com.niit.action.RegistAction">
  2.    <!-- 配置异常处理 -->
  3.    <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
  4.    <result name="success">/WEB-INF/success.jsp</result>
  5.    <!-- 配置异常处理后跳转的视图 -->
  6.    <result name="error">/WEB-INF/error.jsp</result>
  7. </action>


可以配置全局异常处理
     
     
  1. <package name="niit" extends="struts-default" namespace="/user">
  2. <!-- 配置全局result -->
  3. <global-results>
  4. <result name="exception">/WEB-INF/error.jsp</result>
  5. </global-results>
  6. <!-- 配置全局异常处理,一般会结合global-results使用 -->
  7. <global-exception-mappings>
  8. <exception-mapping result="exception" exception="java.lang.Exception"></exception-mapping>
  9. </global-exception-mappings>
  10. </package>




类型转换
客户端请求中所有数据都写入request对象,request对象封装的数据都为String类型。
而表单模型中的数据可能为Date类型,实体对象类型。。。。。。

有效的数据类型可以增强系统的安全性,阻止非法数据的侵入。
类型转换器:
        用于将请求中的数据根据Action中指定的数据类型进行转换

类型转化器的分类:
    Struts內建转换器:主要针对基本数据类型进行类型转换
    自定义转换器:Action中出现数组,集合,对象就需要自定义类型转换器

编写的转换器继承ognl.DefaultTypeConverter,也 继承StrutsTypeConverter
StrutsTypeConverter继承了DefaultTypeConverter类,更便于进行操作,提供了字符至对象,对象至字符的双向转换。
继承DefaultTypeConverter  即重写convertValue方法
    
    
  1. import ognl.DefaultTypeConverter;
  2. public class ResigtConverter extends DefaultTypeConverter {
  3. @Override
  4. public Object convertValue(Map context, Object target, Member member,
  5. String propertyName, Object value, Class toType) {
  6. // TODO Auto-generated method stub
  7. return super.convertValue(context, target, member, propertyName, value, toType);
  8. }
  9. }
 
StrutsTypeConverter的相关逻辑也差不多
    
    
  1. public class LoginConverter extends StrutsTypeConverter {
  2. @Override
  3. public Object convertFromString(Map context, String[] values, Class arg2) {
  4. User user = new User();
  5. user.setUserName(values[0]);
  6. user.setPassword(values[1]);
  7. System.out.println("转换器中:"+user.getUserName());
  8. return user;
  9. }
  10. @Override
  11. public String convertToString(Map arg0, Object arg1) {
  12. // TODO Auto-generated method stub
  13. return null;
  14. }
  15. }
String[] values字符串数组封装了所有提交的数据,且文本框的值始终存在,不填则为空字符串。



自定义类型转换器的实现步骤:
(1)编写转换器                        继承StrutsTypeConveter
(2)编写ActionName-conversion.properties,该配置文件在对应action所在包路径下
           如:LoginAction-conversion.properties
     
     
  1. user=com.niit.convert.LoginConverter        
(3)页面中传递的表单元素那么应为表单模型的属性名          private  UserModel user;
    
    
  1. <form action="user/login.action" method="post">
  2. userName:<input type="text" id="userName" name="user">
  3. password:<input type="password" name="user"><br/>
  4. <input type="submit" value="login">
  5. </form>

(4)action中配置result name=“input”
转换器中出现的异常,由拦截器对异常进行处理,并封装在valueStack中。
在转换器出现异常时,action会跳转至result的name属性值为input的视图中。



全局转化器
    全局转换器可以在整个项目中转换对应的数据
    使用步骤:
    (1)编写转换器类
    (2)编写xwork-conversion.properties文件至classpath路径下
    
    
  1. com.niit.model.UserModel=com.niit.convert.Myconversion



OGNL转换器
    基于struts的OGNL引擎自动完成类型转换
    只需要在页面中将name值设定为Action模型.属性
     
     
  1. <form action="user/login.action" method="post">
  2. userName:<input type="text" id="userName" name="user.userName">
  3. password:<input type="password" name="user.password"><br/>
  4. <input type="submit" value="login">
  5. </form>

转换出现的异常
    未处理异常将会导致action执行中断
    页面无法正确呈现数据

struts已经帮我们做了异常处理,只是我们没有进行页面跳转的配置及呈现异常

异常处理机制
    通过conversionError拦截器处理异常
    错误信息写入contextStack中
    查找并访问当前Action的input-result,根据input-result跳转页面

<s:filedError>标签呈现错误信息
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值