• Struts2


    简介

    Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。

    Struts框架是流行广泛的一个MVC开源实现,而Struts2是Struts框架的新一代产品,是将Struts1和WebWork两种技术进行兼容、合并的全新的MVC框架。Struts2框架充分发挥了Struts1和WebWork这两种技术的优势,抛弃原来Struts1的缺点,使得Web开发更加容易。

    Struts2结合Webwork的优势: 
    (1)Struts2支持更多表现层技术,有更好的适应性。 
    (2)Action无须跟Servlet API耦合,使得测试更加容易,同时提高代码重用性;而且不耦合任何Servlet API(拦截器机制) 
    (3)Struts2具有更好的模块化和可扩展性(插件机制)。

    Struts2框架结构与工作原理

    Struts2是以WebWork为核心,采用拦截器机制对用户的请求进行处理

    框架结构: 

     

    工作流程: 
    (1)客户端浏览器发送HTTP请求到Web应用 
    (2)Web容器将请求传递到标准ActionContextCleanUp过滤器以消除属性,而不让后续过滤器清楚,以延长Action中属性(包括自定义属性)的生命周期。ActionContextCleanUp作用 
    (3)再经过如stimesh等其他过滤器后,请求传递给StrutsPrepareAndExecuteFilter核心控制器 
    (4)StrutsPrepareAndExecuteFilter调用ActionMapper(Action映射器)确定调用哪个Action,再将控制权转移给ActionProxy代理 
    (5)ActionProxy代理调用配置管理器ConfigurationManager从配置文件struts.xml中读取配置信息,然后创建ActionInvocation对象 
    (6)ActionInvocation在调用拦截器链中的拦截器后再调用Action,根据Action返回的结果字符串查找对应的Result 
    (7)Result调用视图模板,再以相反的顺序执行拦截器链,返回HTTP响应 
    (8)HTTP响应以相反的顺序返回给核心控制器StrutsPrepareAndExecuteFilter以及其他web.xml中定义的过滤器,最终返回给客户端

    Struts2使用:

    使用步骤

    1.导入Struts2核心jar包在web.xml配置前端控制器filter

     

    <filter>

        <filter-name>Struts2</fileter-name>

        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

    </filter>

    <filter-mapping>

        <filter-name>Struts2</filter-name>

        <url-pattern>/*</url-pattern>

    <filter-mapping>

     

     web.xml中配置核心控制器StrutsPrepareAndExecuteFilter 
    任何MVC框架需要与Web应用整合时都需要借助web.xml配置文件,由于StrutsPrepareAndExecuteFilter本质上是一个过滤器,在web.xml中用< filter>以及< filter-mapping>进行配置。而Web应用加载了StrutsPrepareAndExecuteFilter之后就有了Struts2的基本功能。

    配置核心控制器StrutsPrepareAndExecuteFilter就是用其实现类过滤所有的请求。Struts-2.5.8版本中的核心控制器实现类更改为org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter

    2.创建struts.xml(格式可以参考核心包根路径下的DTD文件,struts-default.xml)

        编写控制器Action

          - 方法是public的

          - 返回值为String类型(返回值与struts.xml->action->result的name属性匹配,即根据此返回值找到对应result)

          - 参数列表为空

        创建JSP页面

        配置struts.xml

    <struts>

        <!--

            package:包,用于对Action进行封装

            name:包名,根元素下可以有多个包,彼此不能重名

            extends:继承,用于指定继承的包,相当于将继承包下的配置信息复制到当前包

            namespace:命名空间,用于规定Action的访问路径,必须“/”开头    -->

        <package name="test01" namespace="/test01" extends="struts-default">

            <!--action:业务控制器,用于注册业务控制器组件

                name:action名称,用于规定Action的访问路径

                class:业务控制器组件,用于指定业务控制器对应的类

                method:方法,用于指定访问当前action时要调用的方法

                *请求URL:http://ip:port/projectName/namespace/ActionName.action

            -->

            <action name="hello" class="test01.konrad.action.HelloAction" method="execute">

                <!--result:输出组件,用于转发、重定向、直接输出

                    name:名称,一个action下可以有多个result,彼此不能重名

                    默认值转发,元素内设置转发的页面

                -->

                <result name="success">

                    /hello.jsp

                </result>

            </action>

        </package>

    </struts>

    3、参数传递

      1.Action从页面取值  

        a)基本属性注入(页面,Action)

        

        b)域模型注入(页面,Action)

        

      2.页面从Action取值

        a)使用EL表达式

         

        b)OGNL

    4、OGNL

       1.概念:Object Graph Navigation Language,是一门功能强大的表达式语言,类似于EL。Strut2默认采用OGNL表达式访问Action的数据,实际上是通过ValueStack对象来访问Action。

      2.用法:在Struts2中,OGNL表达式要结合Struts2标签来访问数据

        EL:${user.userName} <==> OGNL:<s:property value="user.userName">

        *a)访问基本属性  <s:property value="属性名"/>

        *b)访问实体对象  <s:property value="对象名.属性名"/>

        c)访问数组/集合  <s:property value="someArray[1]"/> | <s:property value="someList[1]"/>

        d)访问Map  <s:property value="someMap.key" />

        e)运算  <s:property value="'My name is' + name" />

        f)调用方法  <s:property value="name.toUpperCase()" />

        g)创建集合  <s:property value="{'a','b','c'}" /> ArrayList

        h)创建Map  <s:property value="#{'mm':'MM','nn':'NN'}" /> LinkedHashMap

          

    5、ValueStack

      1.概念:是Struts2中,Action向页面传递数据的媒介,封装了Action的数据,并允许JSP通过OGNL来对其访问

      2.原理

      

      3.访问ValueStack

        a)通过<s:debug>观察其结构

        b)输出栈顶:<s:property />

        c)访问Context对象:

          - OGNL表达式以"#"开头

          - 以key来访问context对象的值,即"#key"得到context中某属性值

        d)迭代集合  

         

        

        e)按数字迭代

     

       4.ValueStack栈顶的变化

        - 默认情况下栈顶为Action

        - 循环过程中,栈顶为循环变量(集合迭代时,循环变量是集合中的对象,即栈顶为实体对象,可以以实体对象为root来写OGNL表达式;数字迭代时,循环变量是数字,不能以数字为实体对象,需要通过var声明变量名,以"#变量名"来引用,此情况下,是从context对象中取出值)

        - 循环结束后,栈顶变回Action

      5.EL表达式访问ValueStack

        a)EL也是从ValueStack中取的值

        b)EL默认的取值范围是page,request,session,application

        c)Struts2重写的request的getAttribute方法,先试图从原始request中取值,如果没取到再从ValueStack中取值

     

    6、Action基本原理

       1.6大核心组件

      

      FC:前端控制器,负责统一的分发请求

      Action:业务控制器,负责处理某一类业务

      ValueStack:Action与JSP数据交互的媒介

      Interceptor:拦截器,负责扩展Action,处理Action的共通事务

      Result:负责输出的组件

      Tags:标签,负责显示数据、生成框体

      

      2.获取Session的方式

        a)ActionContext

          - ActionContext.getContext().getSesion(),返回Map<String, Object>

        b)ServletActionContext

          - ServletActionContext.getRequest().getSession(),返回HttpSession

        c)SessionAware(推荐使用)

          - 让Action实现SessionAware接口

          - 实现setSession(Map<String, Object> session)方法,Struts2会在实例化Action后调用方法,通过方法参数将Session对象注入进来

          - 定义成员变量,接收注入进来的Session对象

     

    7、Result原理

       1.介绍:用于做输出的组件,用于向页面输出一些内容,转发、重定向可以理解为特殊方式的输出。每一个Result实际上是一个类,这些类都实现了共同的接口Result。Struts2预置了10种类型的Result,定义在strtus-default.xml

      2.Result类型

        a)dispatcher:用于转发的result,可以将请求转发给JSP,这种类型的Result对应的类为ServletDispacherResult,通过default="true"指定该Result为Struts2默认的Result类型。

        b)stream:用于向页面输出二进制数据,此种类型的Result可以将二进制数据输出到请求发起端,对应类为StreamResult

    <result name="success" type="stream">
      <!--codeStream 为定义在Action的输入流InputStream -->

        <param name="inputName">codeStream</param>

    </result>

        c)redirectAction:用于将请求重定向给另外一个Action,对应类为ServletActionRedirectResult

    <result name="login" type="redirectAction">

        <!--若重定向的Action与当前Action在同一个namespace下,可以省略namespace-->

        <param name="namespace">

        /命名空间

        </param>

        <param name="actionName">

        action名

        </param>

    </result>

        d)json:用于向页面输出json格式的数据,可以将json字符串输出到请求发起端。对应类为JSONResult

    <result name="success" type="json">

        <!--输出一个Action属性

        指定属性为基本类型,则直接返回该属性值

        如果指定属性为实体对象,则返回格式{"code":"as1","name":"hk"}

        -->

        <param name="root">属性名</param>

        <!--输出多个Action属性-->

        <param name="includeProperties">属性名1,属性名2...</param>

        <!--输出所有属性,不需要param标签-->

      

    </result>

        json需要导包,修改package继承关系为json-default

    8、UI标签

      1.表单  <s:form action="" method="" theme="simple" ></s:form>

      2.文本框  <s:textfield name="userName" />

      3.布尔框  <s:checkbox name="marry" />

      4.单选框  <s:radio name="sex" list="#{'M':'男','F':'女'}"/> 静态初始化

            <s:radio name="favoriteCities" list="cities" listKey="cityCode" listValue="cityName" /> 动态初始化

      5.多选框  <s:checkboxlist name="travelCities" list="#{'01':'北京','02':'上海','03':'广州'}" /> 静态初始化

            <s:checkboxlist name="travelCities" list="cities" listKey="cityCode" listValue="cityName" /> 动态初始化

      6.下拉选  <s:select name="home" list="#{'01':'北京','02':'上海','03':'广州'}" /> 静态初始化

            <s:select name="home" list="cities" listKey="cityCode" listValue="cityName" /> 动态初始化

    9、拦截器

      1.用途:拦截器适合封装一些通用处理,便于重复利用。例如请求参数传递给Action属性,日志的记录,权限检查,事务处理等。拦截器是通过配置方式调用,因此使用方法比较灵活,便于维护和扩展。

      2.使用步骤

        创建拦截器组件(创建一个类,实现Interceptor接口,并实现intercept方法;也可以继承MethodFilterInterceptor,这种方式可以使action中某个方法不进行拦截)

    public String intercept(ActionInvocation invocation){

       //拦截器--前部分处理

       invocation.invoke();

       //拦截器--后续处理     

    }

        注册拦截器

    <package>

        <interceptors>

            <interceptor name="别名" class="实现类"/>

            <!--其他拦截器-->

        </interceptors>

    </package>

        引用拦截器(哪个Action希望被拦截器扩展,需要在此action配置下,引用拦截器)

    <action>
       <!--手动的使用一次系统默认的拦截器-->
       <interceptor-ref name="defaultStack"/>

        <interceptor-ref name="拦截器别名"/>

        <!--可以写多个-->
       <!--可以使用excludeMethods参数属性,设置不过滤的方法-->

    </action>

      

      3.拦截器栈

    <interceptor-stack name="myStack">

        <interceptor-ref name="拦截器别名1"/>

        <interceptor-ref name="拦截器别名2"/>

    </interceptor-stack>

      4.FileUpload拦截器

        a)原理:首先FileUpload拦截器将表单中提交的文件,以临时文件的形式保存到服务器临时路径下。之后FileUpload拦截器将该临时文件对象注入给Action,Action自主处理该临时文件。最后FileUpload拦截器删除临时文件。

        b)使用步骤

          导包 commons-io.jar

          Action:定义File类型属性(如some),接受拦截器注入的临时文件对象。若想要获取原始文件名,要定义String类型属性,属性名为File类型属性+FileName(如someFileName)

          表单设置:method="post", enctype="multipart/form-data"

        c)设置限制(Struts2文件上传默认最大值为2097152B,即2M)

          在struts.xml中重置默认限制值  <constant name="struts.multipart.maxSize" value="5000000" />

  • 相关阅读:
    【网络】【操作系统】select、poll、epoll
    【JMM】java内存模型及volatile关键字底层
    【数据库】连接查询(from 内连接 外连接)
    【数据库】SQL牛客练习关键点复习
    【SpringMVC】文件/图片 的下载与上传
    【SpringMVC】拦截器实现与网页跳转步骤
    什么是hashMap,初始长度,高并发死锁,java8 hashMap做的性能提升
    自己写一个HashMap
    String去除重复字符两个方法
    Solr与Elasticsearch比较
  • 原文地址:https://www.cnblogs.com/zeussbook/p/9146651.html
Copyright © 2020-2023  润新知