struts2 相关知识

1)为什么要学习Struts框架

     Struts框架是MVC设计模式的实现,基于Struts开发可以简化开发难度,提高开发效率。

2)为什么使用MVC

      MVC是一个非常优秀的设计思想,基于该思想架构程序,可以提高程序的结构灵活性,便于日后维护、扩展和升级。

3)MVCJavaWeb中的实现

       Servlet,JSP,Filter,JDBC

  a.ShoppingCart程序就是一个MVC结构实现

View实现部分:采用JSP组件实现

Model实现部分:采用DAOEntity等组件实现

Controller实现部分:采用ActionServlet组件实现

  b.ShoppingCart程序虽然基于MVC,但结构还有一些问题

     当请求数量比较多时,需要在Servlet中编写大量的if...else分支语句,而且Servlet代码量非常多。

     改造方案:为Servlet提供一个XML配置文件,用于定义请求和Action组件的对应关系。然后将if...else分支中的代码提取到对应的Action组件中。

*4) Struts2的主要工作流程

   a.首先客户端浏览器发送一个请求,请求到达控制器。

   b.控制器根据xml配置信息调用相应的Action组件(XML配置了请求和Action对应关系)

   c.执行Action组件业务处理,该组件可以调用DAO,Cart,Entity等组件。

   d.控制器调用JSP视图组件生成一个响应界面给浏览器

5Struts的内部原理:

    编程原理:

         用户发送http请求---Web服务器(tomcat)--》加载

         web.xml(web部署描述文件)文件-执行struts核心控制器(

         StrutsPrepareAndExecuteFilter或者filterDispatcher)-->

         加载struts.xml文件,通过请求action名字找到匹配的action

         -->action中调用(execute)(业务层|数据层)

          -->执行result="-->

         通过result 找到struts.xmlresult名字匹配结果--》转发到

         页面返回给调用者

    

    程序调用:

struts内部原理图:

 

(1)用户发送http请求--》启动web服务器---》加载web.xml(web部署描述文件)配置文件---》执行web.xml中相应过滤器

              ActionContextCleanUp:清除页面中的属性

              other filter(SiteMesh:装饰过滤器)

                  SiteMesh作用:页面布局、装饰

              FilterDispatcherstruts2核心控制器   

       注意:(a)使用SiteMesh(装饰过滤器),struts2容器不在管理页面中属性,需要调用ActionContextCleanUp完成销毁

              (b)过滤器执行是有顺序

                  ActionContextCleanUp-->SiteMesh-->FilterDispatcher

 (2)中央控制器FilterDistpacher询问ActionMapper是否需要请求action

(3)如果需要请求action,FilterDispatcher就会调用它的代理(ActionProxy)加载配置文件

(4)ActionProxy会调用Configuration Manager读取strus.xml配置文件

           注意:只加载一次   

(5)根据请求名字,ActionProxy(action代理)调用所有拦截器(Inertceptor),ActionProxy(action代理)创建Action Invocation,去执行所对应action类,根据Action类中名字找到匹配result页面

(jspfreeMarkerVelocity)等技术,在此执行拦截器

        注意:struts2拦截器和servlet过滤器功能相同,并比filter强大

              拦截器执行顺序:先进后出

(6)相应给用户(HttpServletResponse)

3.Struts2框架的历史

    Struts2框架和Struts1没有必然联系,它是将原来的WebWork框架核心部分Xwork提取,进行封装后发布为Struts2

*4.Struts2框架基本使用

    *1Struts2使用步骤

        *a.下载发布包,将核心包导入web工程

               struts2-core-2.1.8.jarStruts2核心包

               xwork-core-2.1.6.jar : Xwork核心包

               ognl-2.7.3.jar OGNL技术工具包,与EL相似,但比EL强大。

               freemarker-2.3.15.jar:界面模板技术,与JSP相似。

               commons-fileupload-1.2.1.jar :文件上传包。

        *b.配置Struts2控制器,在src下添加struts.xmlStruts2控制器采用的是StrutsPrepareAndExecuteFilter组件实现。

          在web.xml文件中配置该Filter组件。

          c.根据请求编写Action,DAO,Entity等组件

    *2HelloWord示例

         welcome.action-->struts2控制器-->WelcomeAction-->welcome.jsp

 ----------------------Struts2详细工作流程---------------------------

         a.浏览器发出welcome.action请求

         b.请求到达StrutsFilter控制器(由于web.xml配置)

         c.Struts控制器判断请求类型,如果是/welcome.action/welcome格式请求,将调用struts.xml配置,寻找对应的Action组件

         d.调用Action组件的execute方法处理请求,最后返回一个String视图标识

         e.Struts控制器根据视图标识寻找相应的JSPstruts.xmlresult配置)

         f.调用JSP视图生成响应界面给浏览器显示。

        ======================Day02=========================

 

1.Struts2使用基本规则

1web.xml配置

         涉及了Struts2Filter控制器配置

         a.<filter-class>指定正确包名.类名

         b.<url-pattern>指定/*,控制器可以识别Action组件请求

2Action编写规则

         a.执行方法的定义public String XXX(){} 默认方法名是execute

         b.属性变量的定义

             public class User{

                 private String username;//成员变量是username

//属性是user

                 public void setUser(String user){

                        this.username = user;

                 }

                 public String getUser(){

                        return username;

                 }

             }

 

       注意:如果action需要接收请求数据或向JSP传递数据,需要与属性名保持一致。

     3struts.xml中的Action配置

         1)元素嵌套顺序<struts>--><package>--><action>--><result>

         2)<package>元素的extends属性必须继承自struts-default

         3)<action>元素name请求名不要加.actionclass指定的Action类要正确。

         4)<result>元素的name属性与Action方法返回值保持一致。

2.实现一个列表显示功能

    /list.action-->ProjectListAction-->projectlist.jsp

   1)开发步骤

     a.引入struts2和数据库的驱动包

     b.添加struts.xml配置文件,web.xml添加了Struts控制器配置

     c.添加DBUtil工具类

     d.添加Entity

     e.添加DAO编写方法

     f.添加Action

     g.添加Action配置(struts.xml

     h.添加JSP,显示列表

         引入jstl标签库的jar包。

         在JSP页面添加标签库引入指令

         使用<c:forEach>标签

limit begin,size

begin = (page-1)*size

page    begin

1           0

2           3

3           6

n           (n-1)*3

===========================

Struts2标签+OGNL表达式

 3. OGNL表达式

    1)什么是OGNL

      OGNL技术可以独立使用,封装在ognl.jar开发包中。

Object Graphics Navigation Language 对象图导航语言。主要作用是对一些复杂对象的属性和方法进行访问。

     EL表达式主要功能:用于访pageContext,request,session,application范围内存储的数据。

     OGNL不仅可以访问数据,还具有访问方法,对集合进行操作等功能。

   2OGNL工作原理

 

OGNL工具由三部分构成,分别是

   a. OGNL引擎:负责解释执行OGNL表达式,按表达式区rootmap区域寻找数据。

   b. Root根对象区域:访问该区域数据OGNL表达式简洁方便。适合放置访问频繁的对象元素。         

   c. Map对象存储区 :访问该区域需要使用“#key”访问。适合放置访问不频繁的对象元素。

   使用时,给OGNL引擎指定一个表达式,该引擎根据表达式去Root区或Map区访问对象的属性或方法。

*3OGNL表达式语法

  a.访问Root对象某个简单属性

             表达式: "属性名"

  b.访问Root对象某个数组或者List集合

             表达式:"属性名[0]"

  c.访问Root对象某个Map集合

              表达式:"属性名.key"或者"属性名['key']"

  d.访问Root对象某个复合类型属性address

               表达式: "address.子属性"

  e.访问Root对象某个复杂属性 List<Address> addresses

                表达式:"addresses[0].子属性"

  f.访问Root对象的某个属性的方法

                 表达式:"属性名.方法()"

  g.支持Java中的表达式和运算符

  h.定义一个List常量 

               表达式:{"A","B","C"}

  i.定义一个Map常量

                表达式:#{"key1":value1,"key2":value2}

  j.访问静态常量或方法

                表达式:"@包名.类型@常量名或方法"

  上述语法如果访问Map区域一样使用,只要注意追加"#key".

==================================================

 4.OGNLStruts2中的应用

1xworkognl进行扩展和改造

     xworkOGNL原有的Root区域进行了改造,将其扩建成了一个栈结构。可以存储多个目标对象。当输入"id"表达式时,首先去栈顶对象寻找id属性值,没有再去次栈顶,依次向下寻找,找到返回。

*2ValueStack对象(参考valuestack.jpg)

      Struts2将扩展之后的OGNL封装成了ValueStack对象,利用该对象存储当前请求相关的所有数据。例如action,request,session,application等。

   root栈:存储了action对象

  contextmap)区:存储了request,session,application等对象引用。

*3)在JSP中访问ValueStack数据方法

    a.使用Struts标签+OGNL表达式

<s:debug>:可以显示当前状态的ValueStack信息

    <s:property>:显示ValueStack数据。使用value属性指定OGNL表达式

    <s:date>:ValueStack的日期类型数据格式化后显示。使用 name属性指定OGNL表达式,format属性指定格式化模板。

    <s:iterator>:ValueStack的集合属性迭代循环。使用value属性指定OGNL表达式。

    <s:if>...<s:else>:分支判断。使用test属性指定一个OGNL判断表达式

     b.使用EL表达式

       EL表达式可以从pageContext,request,session,application范围获取数据,显示到页面。但是在Struts2中利用EL表达式可以访问到ValueStack中的数据。

       *Struts2EL表达式依次访问pageContext,request,valuestack,session,application范围的数据。

   

=================原因如下=====================

JSP--${user} --request.getAttribute("user");

Struts2中,将原有的Request对象封装成StrutsRequestWrapper,并重写它的getAttribute()方法。

public class StrutsRequestWrapper extends HttpServletRequestWrapper{

       //覆盖原requestgetAttribute

       public Object getAttribute(String name){

       //去原有的request对象中查找信息

   Object val = super.getAttribute(name);

                //如果原有的request找不到

                if(val == null){

                    //valuestack查找

                    vs.findValue(name);//--->Ognl.getValue("name",ctx,root)

                }

               return val;

       }

}

${user}-->request.getAttribute("user")-->Ognl.getValue("user",ctx,root)

======================Day03=========================

1.Struts2框架Action组件的核心应用

   1Action组件基本原理

       a.当浏览器发送一个请求给Struts2控制器

       b.控制器要创建一个ValueStack对象,将其存储在request中,使用struts.valueStack当做key

       c.控制器创建一个Action对象,并Action对象添加到ValueStack对象栈顶位置。

       d.控制器将request封装之后,再将request,session,application等对象添加到ValueStackcontext(Map)区域。

       e.控制器调用Action对象的业务方法,处理请求。默认调用execute

       f.控制器根据execute返回结果,调用result视图响应

上述过程:Action对象在请求处理完毕后销毁,因此与request对象生命周期相同。

    *2)如何在Action中使用request,session,application等对象

        a.采用Aware接口方式注入到Action(推荐在Action中使用)

         如果获取Map结构的可以使用RequestAware,SessionAware,ApplicationAware接口。

如果获取Servlet类型的可以使用ServletRequestAware,

ServletResponseAware,ServletContextAware

b.采用ActionContext工具类方式使用(推荐在Action之外使用)

              ActionContext方法获取Map结构的ServletActionContext方法获取Servlet应用类型的

==========如何将request封装成Map结构===============

public class RequestMap extends AbstractMap{

     private HttpServletRequest request;

      public RequestMap(HttpServletRequest request){

this.request = request;

      }

      //重写抽象Map的方法

     public void put(Object key,Object value){

request.setAttribute(key.toString(),value);

     }

     public Object get(Object key){

Object val = request.getAttribute(key.toString());

return val;

     }

}

同理,SessionMap,ApplicationMap都做过类似封装

=======================================

*3Action属性注入

     指的是在action配置时,为Action对象的属性指定值。

        <action>

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

        </action>

       在action对象创建完毕后,会自动调用属性的setter方法设置值。

*4)如何利用一个Action处理多个请求

  a.action配置时使用通配符*

    在<action>元素的name属性中可以使用若干个*号,然后在其他属性中可以使用{1},{2}格式引用第1个、第2*号所代表的字符串信息

  *b.使用动态方法调用(推荐)

      可以在发请求时,指定action方法名。

      请求格式:请求名!方法名.action

=====================================

作业:扩展Project列表显示功能

  添加任务,删除任务,更新任务,查看任务

1.前期课程回顾

   1MVC结构,优势,工作流

   2Struts2MVC实现和基本使用

         C部分:StrutsPrepareAndExecuteFilterAction

         V部分:主要由JSP实现,当然也可以是图形、报表、流当响应。

                       (Struts2标签+OGNL表达式)Result组件。

         M部分:业务逻辑模型(DAO,Service,数据模型(实体对象、Action属性)ValueStack组件

   3Struts2的工作流程

=================================

   4OGNL语法

   5ValueStack结构和数据

   6)掌握几个常规标签

   7ELStruts2中的访问范围

         pageContext,request,valuestack(action),session,application

====================================

   8Action如何使用request,session,application

   9Action属性注入

   10Action封装多个请求处理

        通配*号的使用

        动态方法调用方式使用

 

------------------------------ Day04-----------------------------------

1.Result组件原理

 1Result组件的作用

    负责调用视图组件,生成响应内容。Struts2提供了各种类型的响应Result组件,用于JSP页面、流、JSON、图形、报表等响应类型。

 2Result组件实现规则

     a.Result组件实现类

        必须实现Result接口,实现接口约定execute()方法。

     b.Result组件的声明定义

           在strutsXML配置中,使用如下格式:

           <package>

               <result-types>

                    <result-type name="类型" class="实现类"/>

                    ... ...

               </result-types>

           </package>

      *c.Result组件的使用

        首先<result>元素所在的package必须能找它的定义。

        利用<result>元素的type属性指定使用的Result类型,默认值为             dispatcher

========================================

public class RedirectResult implement Result{

       private String location;//接收注入的URL地址

       //settergetter

       public void execute(){

             //重定向

             HttpServletResponse res = ServletActionContext.getRequest();  

             res.sendRedirect(location);

       }

}

<package  >

    <resut-types>

         <result-type name="myRedirect" class="...RedirectResult"/>

    </result-types>

    <action>

<result type="myRedirect">/login.jsp</result>

    </action>

</package>

=================================

 *2.常用的几种Result组件

    1JSP响应

         dispatcher :采用请求转发方式调用JSP组件响应。

         redirect:采用请求重定向方式调用JSP组件响应。(在重定向后,原requestaction都被销毁掉,因此在JSP获取不到值)

       使用格式如下:

       <result type="dispatcher">

      <param name="location">/msg.jsp</param>

       </result>

       或者使用简写

       <result type="dispatcher">

           /msg.jsp

       </result>

    2Action响应

         delete.action?id=1---->DeleteAction--->ListAction--->list.jsp

         redirectAction:采用重定向方式发出一个*.action请求

         chain:采用转发方式发出一个*.action请求

         使用格式如下:

             调用不同命名空间的action时:

           <result type="redirectAction">

                <param name="actionName">请求名</param>

                <param name="namespace">命名空间</param>

           </result>

              调用相同命名空间的action时:

           <result type="redirectAction">

请求名

           </result>

-->*.action--->Action1--chain-->Action2---chain-->Action3

     3)流响应

        典型功能:验证码和下载。

         stream:可以将Action中的一个InputStream类型属性以流方式响应输出。

        使用格式如下:

       <result type="stream">

    <param name="inputName">Action属性</param>

       </result>

    4JSON响应

      负责对Ajax请求进行数据响应。

      json:可以将Action中的一个属性或多个属性以json格式响应输出使用格式如下:

         如果需要返回一个属性值

         <result type="json">

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

         </result>

          如果需要返回多个属性值

         <result type="json">

              <param name="includeProperties">

Action属性1,Action属性2

              </param>

         </result>

  如果需要返回所有属性值

        <result type="json"></result>

     注意:使用前需要引入struts-json-plugin.jar,然后将<package>元素的extends设置成"json-default"

==============作业===============

完成验证码和ajax校验案例

完成任务列表的增加,删除,修改,查看,分页显示

==========================Day05 ============================

 

1.Struts2标签

    主要用于简化JSP代码,用于显示模型中的数据。

1)通用标签

          property,date,iterator,if...else..

2)表单标签

     textfield,password,hidden,textarea,checkbox,radio,select

     a. textfield,password,hidden,textarea

        利用name属性指定ognl表达式

     b.checkbox

        利用name属性指定ognl表达式,该属性值用boolean

     c. radio,checkboxlist,select

        利用list属性指定ognl表达式,指定一个集合。标签可以根据该集合动态生成元素。listKey指定的属性值为不可见valuelistValue指定的属性值为用户可见;

         利用name属性指定值,控制哪些元素选中。

示例:form.action--->FormAction--->form.jsp

=======上午标签案例练习:20分钟=========

2.拦截器组件

   1)拦截器组件规则   add.action(表单数据)--->params

        *a.拦截器组件的作用(工作流)

           --客户端发送请求,请求到达Filter控制器

           --控制器根据请求信息创建ValueStack对象并实例化

           --控制器调用一系列的Interceptor拦截器前期处理(defaultStack)

              invocation.invoke();

           --控制器调用Action组件,执行execute方法

           --控制器调用Result组件,解释JSP标签

           --控制器调用一系列的Interceptor拦截器后续处理

           --将生成的响应信息输出

         拦截器可以在ActionResult调用之前和之后添加处理逻辑。因此适合将一些共通处理写成拦截器,实现重复利用。 例如权限检查,日志的记录,以及事务处理等。

          b.拦截器组件的使用规则

            --编写拦截器组件

               编写一个实现类,该类必须实现Interceptor接口,并实现约定               的interceptor()方法。

            --拦截器的声明注册

              <package>

                 <interceptors>

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

                     //... ...

                 </interceptors>

              </package>

             --拦截器的使用

    设置执行默认的拦截器(Action没有指定拦截器时,默认调用)

                 <package name="demo1" extends="struts-default">

                         <default-interceptor-ref name="别名"/>

                 </package>

    为某些Action单独指定拦截器

             <action>

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

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

             </action>

         

 

   *2)掌握自定义拦截器的使用

          注意:当为Action指定了<interceptor-ref/>之后,默认的defaultStack将不会再调用。因此需要使用<interceptor-ref/>引用一下。否则原有机制会出问题,不能缺少。

          

          在拦截器interceptor方法中可以使用以下方法。

            a.如何获取和使用ValueStack对象

              ValueStack vs = invocation.getStack();

              vs.findValue("#request.name");

              vs.setValue("name", "tom");

            b.如何获取request,session,response

              使用ActionContext,ServletActionContext

            c.invocation.invoke()

              调用后续拦截器,如果没有调用ActionResult。当执行该方法后,interceptor方法返回的String视图标识无效。

            d.invocation.invokeActionOnly();

              调用后续拦截器,如果没有调用Action.interceptor方法返回的String视图标识有效。

 

 

   *3)内置拦截器的使用

       a.上传功能

           需要使用Struts内置的fileUpload拦截器完成。

          ---fileUpload拦截器原理

             首先调用指定的上传组件(commons-fileupload.jar)将请求提交的文件解析出来。解析出文件将其放置到一个临时目录下(tomcat/work)。将临时文件对象给Action的属性赋值。

              之后执行invoke()方法调用Actionexecute处理。

             调用ActionResult之后,拦截器将临时文件删除。

          注意:由于defaultStack包含fileUpload因此没有特殊需求可以不用引用。

 

         操作需要注意的问题:

         ---JSP表单中methodenctype属性值

             <input type="file" name="xxx"/>

         ---Action属性定义

             File xxx;

             String xxxFileName;

             String xxxContentType;

         ----jar包引用

             commons-fileupload依赖commons-io.jar

 

       b.下载功能

           需要使用Struts提供的stream类型的Result组件。

 

=========作业练习================

1.完成任务列表的维护操作。

2.追加登录检查的拦截器。

 

 

posted @ 2013-04-10 17:08  志成中国  阅读(277)  评论(0编辑  收藏  举报