Struct2

作者: 蕊er | 来源:发表于2017-11-06 14:11 被阅读0次

    加载流程

    StrutsPrepareAndExecuteFilter Struts2中的核心类,有两个功能:预处理执行

    • 预处理

      • 配置文件加载顺序

        • struts.properties ---- 配置常量name = value

        • struts.xml ---- 配置Action及常量<constant name="" value="">

          使用include进行分模块开发,在struts.xml中包含其他配置文件,被包含的文件都是标准的struts配置文件

          <include file="struts.xml"/>
          <include file="com/sd/struts.xml"/>
          
        • web.xml ---- 配置核心过滤器及常量init-param

          以上三个配置文件均可添加常量,后加载的配置文件中的常量值会将先加载配置文件中的常量值覆盖

    配置常量

    • 国际化,解决post提交乱码

      <constant name="struts.i18n.encoding

    • 指定访问action的后缀名,以下指定后缀为action或不进行配置

      <constant name="struts.action.extension" value="action,,"/>

    • 指定struts2是否以开发模式运行

      • 热加载主配置
      • 提供更多的错误信息输出,方便开发时调试

      <constant name="struts.devMode" value="true"/>

    默认配置

    <struts>
        <package name="demo" extends="struts-default" namespace="/">
            <!-- 如果访问路径404时,跳转到default-action-ref指定action -->
            <default-action-ref name="demo1"/>
            <!-- method 默认为execute()-->
            <!-- result name 默认为success-->
            <!-- result type 默认为dispatcher-->
            <!-- class 默认为com.opensymphony.xwork2.ActionSupport -->
            <action name="demo1">
                <result name="*" type="dispatcher">/welcome.jsp</result>
            </action>
        </package>
    </struts>
    

    Action编写方式

    • 普通POJO类

      定义业务方法,默认为execute()方法public String execute(),也可实现其他方法(需要在struts.xml中定义,method参数执行定义的方法)

    • 实现Action接口,定义了五个字符串常量

      SUCCESS,NONE,ERROR,INPUT,LOGIN

    • 继承ActionSupport类

      提供了许多默认方法,包括获取国际化信息的方法,数据校验方法,默认的用户请求方法等

    Action动态方法调用

    • 通配符配置

      • 配置struts.xml
      <struts>
          <package name="demo" extends="struts-default" namespace="/">
              <global-allowed-methods>regex:.*</global-allowed-methods>
              <action name="demo1_*" class="com.sd.action.Action1" method="{1}">
                  <result name="*">/welcome.jsp</result>
              </action>
          </package>
      </struts>
      

      name属性中的*代表任意字符,method中的{1}代表name属性中出现的第一个 * 所代替的字符

      • 定义

        public String add() {
            System.out.println("增加");
            return SUCCESS;
        }
        
        • 引用

          <h4><a href="${pageContext.request.contextPath}/demo1_add">示例一:增加</a></h4>
          
    • 动态访问(使用!来匹配方法,不符合SEO引擎优化)

      • 开启动态访问struts.xml

        <struts>
            <constant name="struts.enable.DynamicMethodInvocation" value="true"/>
            <package name="demo" extends="struts-default" namespace="/">
                <global-allowed-methods>regex:.*</global-allowed-methods>
                <action name="demo1" class="com.sd.action.Action1">
                    <result name="*">/welcome.jsp</result>
                </action>
            </package>
        </struts>
        
    • 定义

      public String add() {
        System.out.println("增加");
        return SUCCESS;
      }
      
    • 引用

      <h4><a href="${pageContext.request.contextPath}/demo1!add">示例一:增加</a></h4>
      

    Structs2访问servlet API

    • ActionContext

      • HttpServletRequest(获取,设置request参数)

        void put(String key,Object value)

        Object get(String key)

        HttpParameters getParameters()

      • Application

        void setApplication(Map<String,Object> application)

        Map<String,Object> getApplication()

      • Session

        void setSession(Map<String,Object> session)

        Map<String,Object> getSession()

      • ActionContext

        static ActionContext getContext();//获取当前线程的ActionContext 对象

    • ServeletActionContext

    • 通过特定接口访问

      • ServletRequestAware:实现该接口的Action可以直接访问web应用的HttpServletRequest实例
      • ServletResponseAware:实现该接口Action可以直接访问web应用的HttpServletResponse实例
      • SessionAware:实现该接口Action可以直接访问web应用的HttpSession实例
      • SevletContextAware:实现该接口Action可以直接访问web应用的SevletContext实例

    结果页面配置

    • 跳转方式
    //转发到Action
    <result name="*" type="chain">
        <param name="actionName">demo1</param>
        <param name="namespace">/</param>
    </result>   
    
    //转发到JSP
    <result name="*" type="dispatcher">/welcome.jsp</result>
    
    //重定向到JSP
    <result name="*" type="redirect">/welcome.jsp</result>
    
    //重定向到Action
    <result name="*" type="redirect">
        <param name="actionName">demo1</param>
        <param name="namespace">/</param>
    </result>   
    
    • 全局结果页面配置

      在这个包下所有返回相同字符串的值,都可以向这个页面进行跳转

      <global-results>
          <result name="error">/welcome.jsp</result>
      </global-results>
      
    • 局部页面配置

      某个Action中返回的字符串的值,会向这个页面跳转

      <action name="demo1">
          <result name="*" type="dispatcher">/welcome.jsp</result>
      </action>
      

    获得参数的方式

    • 属性驱动

      • 准备与参数键名称相同的属性
      • 自动类型转换,只能转换8大基本数据类型及对应包装类
      • 支持特定类型字符串转化为Date,例如yyyy-MM-dd
    • 对象驱动

    • 模型驱动(实现ModelDriven接口)

      //此处必须手动new 对象,否则会报NPE
      private User userhaha=new User();
      @Override
      public User getModel() {
          return userhaha;
      }
      
    • 集合类型参数封装

      • List

        • 定义

          private List<User> userList;
          public List<User> getUserList() {
                  return userList;
          }
          
          public void setUserList(List<User> userList) {
            this.userList = userList;
          }
          
        • jsp配置

          <form action="${pageContext.request.contextPath}/parm" method="post">
              姓名:<input type="text" name="userList.name"></br>
              年龄:<input type="text" name="userList.age"></br>//userList默认为userList[0]
              生日:<input type="text" name="userList[0].birthday">
              </br>
              </br>
              </br>
              姓名:<input type="text" name="userList[1].name"></br>
              年龄:<input type="text" name="userList[1].age"></br>
              生日:<input type="text" name="userList[1].birthday">
              <input type="submit" value="提交">
          </form>
          
      • Map

        • 定义

          private Map<String,User> users;
          public Map<String, User> getUsers() {
              return users;
          }
          public void setUsers(Map<String, User> users) {
              this.users = users;
          }
          
        • 配置

          <form action="${pageContext.request.contextPath}/param" method="post">
              姓名:<input type="text" name="users['one'].name"><br>
              年龄:<input type="text" name="users['one'].age"><br>
              生日:<input type="text" name="users['one'].birthday"><br>
          爱好:
              跑步:<input type="checkbox" name="users['one'].love" value="run"><br>
              读书:<input type="checkbox" name="users['one'].love" value="book"><br>
              宠物:<input type="checkbox" name="users['one'].love" value="pat"><br>
              联系人1:<br>
              姓名:<input type="text" name="users['two'].name"><br>
              年龄:<input type="text" name="users['two'].age"><br>
              生日:<input type="text" name="users['two'].birthday"><br>
          <%--    联系人2:<br>  
              姓名:<input type="text" name="users['two'].name"><br>
              年龄:<input type="text" name="users['two'].age"><br>
              生日:<input type="text" name="users['two'].birthday"><br>--%>
              <input type="submit" value="提交"><br>
          </form>
          //备注:同一个name值不能出现两次及两次以上
          

    声明式异常处理

    根据<exception-mapping>出现的位置,异常映射分为两种:

    • 局部异常映射:将<excepion-mapping>元素作为<action>元素的子元素配置;
    • 全局异常映射:将<exception-mapping>元素作为<global-exception-mappings>元素的子元素
    <package name="demo" namespace="/" extends="struts-default">
        <global-results>
            <result name="sql">/index.jsp</result>
        </global-results>
        <global-exception-mappings>
            <exception-mapping result="sql" exception="java.sql.SQLException"/>
        </global-exception-mappings>
        <action name="testParams" class="com.ognl.Demo1Action">
            <exception-mapping result="sql" exception="java.sql.SQLException"/>
        </action>
    </package>
    

    全局异常映射对所有的 Action 类都有效,但局部异常映射仅对该异常映射所在的 Action 有效;

    拦截器

    • 生命周期

      生命周期随项目启动创建,随项目关闭而销毁

    • 自定义拦截器

      • 实现Interceptor接口

      • 继承AbstractInterceptor类

      • 继承MethodFilterInterceptor类(方法过滤拦截器)

        定制拦截器拦截方法(拦截哪些方法,哪些方法不拦截)

        @Override
        protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
            /**
             * 拦截器放行,需要调用actionInvocation.invoke()方法,返回null即可,逻辑视图由Action处理
             * 拦截器不放行,不需要调用actionInvocation.invoke()方法,需要返回一个字符串作为逻辑视图,
             *               系统会根据返回的字符串跳转到对应的视图资源
             */
            //前处理
            actionInvocation.invoke();//放行
            //后处理
            return null;//返回逻辑视图
        }
        
    • 配置拦截器

      • 注册拦截器

      • 指定拦截器栈

      • 指定默认拦截器栈,定制方法是否拦截

        <interceptors>
            <!-- 注册拦截器 -->
            <interceptor name="myInters" class="com.interceptor.MyInterceptor"/>
            <!-- 指定拦截器栈-->
            <interceptor-stack name="myStack">
                <!-- 引用定义拦截器 -->
                <interceptor-ref name="myInters">
                    <!-- 不能同时指定 -->
                    <!-- 指定方法不拦截 -->
                    <param name="excludeMethods">add,select</param>
                    <!-- 指定方法拦截 -->
                    <!-- <param name="includeMethods"></param> -->
                </interceptor-ref>
                <!-- 引用默认拦截器 -->
                <interceptor-ref name="defaultStack"/>
            </interceptor-stack>
        </interceptors>
        <!-- 指定默认的拦截器栈 -->
        <default-interceptor-ref name="myStack"/>
        

    OGNL与Struts2的体现(ValueStack)

    ​ 默认情况下,栈(CompoundRoot root)中放置当前访问的Action对象,提供push()pop()方法。Context部分就是ActionContext数据中心

    • 参数接受

      通过ognl来实现原生接受到的参数转换成最终Action对象的参数获取方法(以上三种)

      //获取值栈
      ValueStack stack = ActionContext.getContext().getValueStack();
      stack.push(xxx);
      
    • 配置文件

      <struts>
          <package name="demo" namespace="/" extends="struts-default">
              <action name="testParams" class="com.ognl.Demo1Action">
                  <result name="success" type="redirectAction">
                      <param name="namespace">/</param>
                      <param name="actionName">params</param>
                      <!-- 如果添加的参数 struts "看不懂",则就会作为参数,附加到重定向的路径之后,
                          如果参数是动态的,可以使用${ }包裹ognl表达式动态取值,取值的位置位于ognl
                          的值栈区,即对应的Action对象-->
                      <param name="name">${name}</param>
                  </result>
              </action>
              <action name="params" class="com.ognl.Demo2Action">
                  <result name="*">/index.jsp</result>
              </action>
          </package>
      </struts>
      
      public class Demo1Action extends ActionSupport{
          private String name="李雷与韩梅梅";
      
          @Override
          public String execute() throws Exception {
              return SUCCESS;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      }
      
      http://localhost:8080/params.action?name=李雷与韩梅梅
      
    • Struts2标签

      <%@ taglib prefix="s" uri="/struts-tags" %>

      • Debug

        <s:debug/>

      • 遍历标签

        !-- 遍历标签 -->
        <s:iterator value="#names"  status="st">
            <s:if test="#st.odd">
                <s:property value="#st.index"/><br/>
            </s:if>
            <s:property/><br/>
        </s:iterator>
        
        <s:iterator value="#names" var="name">
            <s:property value="#name"/><br/>
        </s:iterator>
        
        <s:iterator begin="1" end="10" status="1">
            <s:property/>
        </s:iterator>
        
        <br/>
        <s:if test="#names.size()==4">
            list 长度为4
        </s:if>
        <s:elseif test="#names.size()==5">
            list 长度为5
        </s:elseif>
        <s:else>
            list 长度不为4
        </s:else>
        
      • 属性标签

        根据是否带#决定是在ValueStack哪个部分取值

        <s:property value="hello"/><br/>
        <s:property value="hello.length()"/><br/>
        <s:debug/>
        

    相关文章

      网友评论

          本文标题:Struct2

          本文链接:https://www.haomeiwen.com/subject/yrrlmxtx.html