快速學(xué)習(xí)使用springmvc、strust2、strust1以及它們的對比

1、如何快速學(xué)習(xí)springmvc
       首先,我們需要在復(fù)制spring相關(guān)的jar包到web-inf/lib里面去,然后在web.xml里面加入以下代碼,相當(dāng)于springmvc里面的servlet,這里只說明了一些常見的用法,如果要了解springmvc里面的控制器這些詳細原理可以到網(wǎng)上再去找好詳細學(xué)習(xí)。

    <servlet>
            <servlet-name>spring</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:applicationContext.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
     
        <servlet-mapping>
            <servlet-name>spring</servlet-name>
            <url-pattern>*.htm</url-pattern>
        </servlet-mapping>
     
        <servlet-mapping>
            <servlet-name>spring</servlet-name>
            <url-pattern>*.json</url-pattern>
        </servlet-mapping>
           然后再在application.xml里面配置下面代碼,
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                 http://www.springframework.org/schema/beans/spring-beans.xsd    
                 http://www.springframework.org/schema/tx  
                 http://www.springframework.org/schema/tx/spring-tx.xsd   
                 http://www.springframework.org/schema/aop    
                 http://www.springframework.org/schema/aop/spring-aop.xsd   
                 http://www.springframework.org/schema/mvc    
                 http://www.springframework.org/schema/mvc/spring-mvc.xsd  
                 http://www.springframework.org/schema/context    
                 http://www.springframework.org/schema/context/spring-context.xsd
                 http://www.springframework.org/schema/task
                 http://www.springframework.org/schema/task/spring-task.xsd">
     
        <!-- 自動掃描的包名 -->
        <context:component-scan base-package="com.shishuo.studio"></context:component-scan>
     
        <mvc:annotation-driven />
     
        <task:annotation-driven />
     
        <tx:annotation-driven />
     
        <bean
            class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
     
        <bean
            class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
        <!-- 在XML配置文件中加入外部屬性文件,當(dāng)然也可以指定外部文件的編碼 -->
        <bean id="propertyConfigurer" class="com.shishuo.studio.util.PropertyUtils">
            <property name="locations">
                <list>
                    <value>classpath:shishuo.studio.properties</value> <!-- 指定外部文件的編碼 -->
                </list>
            </property>
        </bean>
     
        <!-- FreeMarker的配置 -->
        <bean id="freeMarkerConfigurer"
            class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
            <property name="templateLoaderPath" value="/WEB-INF/ftl" /><!--
                指定路徑 -->
            <property name="defaultEncoding" value="UTF-8" /><!-- 指定編碼格式 -->
            <property name="freemarkerSettings">
                <props>
                    <prop key="template_update_delay">10</prop>
                    <prop key="defaultEncoding">UTF-8</prop>
                    <prop key="url_escaping_charset">UTF-8</prop>
                    <prop key="locale">zh_CN</prop>
                    <prop key="boolean_format">true,false</prop>
                    <prop key="time_format">HH:mm:ss</prop>
                    <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
                    <prop key="date_format">yyyy-MM-dd</prop>
                    <prop key="number_format">#.##</prop>
                    <prop key="whitespace_stripping">true</prop>
                    <prop key="classic_compatible">true</prop>
                </props>
            </property>
        </bean>
     
        <!-- 配置 FreeMarker視圖解析器 -->
        <bean id="viewResolver"
            class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
            <property name="viewClass"
                value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"></property>
            <property name="cache" value="false" />
            <property name="prefix" value="/" />
            <property name="suffix" value=".ftl" /><!--可為空,方便實現(xiàn)自已的依據(jù)擴展名來選擇視圖解釋類的邏輯 -->
            <property name="contentType" value="text/html;charset=utf-8" />
            <property name="exposeRequestAttributes" value="true" />
            <property name="exposeSessionAttributes" value="true" />
            <property name="exposeSpringMacroHelpers" value="true" />
        </bean>

我們試圖模板用的是freemarker,所以后綴名是以.ftl結(jié)束,如果是用的jsp,那這個配置文件里面的

    <property name="suffix" value=".ftl" />valeu改為.jsp

然后我再給出類給大家看見

    package com.shishuo.studio.action;
     
    import org.apache.log4j.Logger;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
     
    import com.shishuo.studio.constant.SystemConstant;
    import com.shishuo.studio.entity.Category;
    import com.shishuo.studio.entity.vo.CourseVo;
    import com.shishuo.studio.entity.vo.PageVo;
    import com.shishuo.studio.exception.CategoryNotFoundException;
    import com.shishuo.studio.exception.notfound.StorageNotFoundException;
    import com.shishuo.studio.service.CategoryService;
    import com.shishuo.studio.service.UserService;
     
    /**
     * @author Herbert
     *
     */
    @Controller
    @RequestMapping("/category")
    public class CategoryAction extends BaseAction {
     
        protected final Logger logger = Logger.getLogger(this.getClass());
     
        @Autowired
        protected CategoryService categoryService;
     
        @Autowired
        protected UserService userService;
     
        /**
         * 首頁
         *
         * @param modelMap
         * @return
         */
        @RequestMapping(value = "/{categoryId}.htm", method = RequestMethod.GET)
        public String category(@PathVariable long categoryId, ModelMap modelMap,
                @RequestParam(value = "p", defaultValue = "1") int p) {
            try {
                // 獲得數(shù)據(jù)
                Category category = categoryService.getCategoryById(categoryId);
                // 獲取當(dāng)前目錄下的所有課程
                PageVo<CourseVo> coursePageVo = courseService
                        .getCoursePageByIdForUser(categoryId, p, 24);
                // 增加屬性
                modelMap.addAttribute("category", category);
                modelMap.put("coursePageVo", coursePageVo);
                return "category";
            } catch (CategoryNotFoundException e) {
                return SystemConstant.PAGE_404;
            } catch (StorageNotFoundException e) {
                // TODO Auto-generated catch block
                return SystemConstant.PAGE_404;
            }
     
        }
    }
     
    package com.shishuo.studio.action;
     
    import javax.servlet.http.HttpServletRequest;
     
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
     
    import com.shishuo.studio.action.auth.AuthBaseAction;
     
    @Controller
    @RequestMapping("/about")
    public class AboutAction extends AuthBaseAction {
     
        /**
         * 跳轉(zhuǎn)到關(guān)于我們頁面
         *
         * @param modelMap
         * @param request
         * @return
         */
        @RequestMapping(value = "/about.htm", method = RequestMethod.GET)
        public String about(ModelMap modelMap, HttpServletRequest request) {
            return "/about/about";
        }
     
        /**
         * 跳轉(zhuǎn)到服務(wù)協(xié)議頁面
         *
         * @param modelMap
         * @param request
         * @return
         */
        @RequestMapping(value = "/service.htm", method = RequestMethod.GET)
        public String service(ModelMap modelMap, HttpServletRequest request) {
            return "/about/service";
        }
     
        /**
         * 跳轉(zhuǎn)到投訴舉報頁面
         *
         * @param modelMap
         * @param request
         * @return
         */
        @RequestMapping(value = "/complain.htm", method = RequestMethod.GET)
        public String complain(ModelMap modelMap, HttpServletRequest request) {
            return "/about/complain";
        }
     
        /**
         * 跳轉(zhuǎn)到版權(quán)聲明頁面
         *
         * @param modelMap
         * @param request
         * @return
         */
        @RequestMapping(value = "/copyright.htm", method = RequestMethod.GET)
        public String copyright(ModelMap modelMap, HttpServletRequest request) {
            return "/about/copyright";
        }
     
        /**
         * 跳轉(zhuǎn)到聯(lián)系我們頁面
         *
         * @param modelMap
         * @param request
         * @return
         */
        @RequestMapping(value = "/connect.htm", method = RequestMethod.GET)
        public String connect(ModelMap modelMap, HttpServletRequest request) {
            return "/about/connect";
        }
     
    }

下面是使用springmvc的經(jīng)驗:

return "system/comment/comment";后面不需要東西

return "redirect:/admin/comment/page.htm";一般當(dāng)我改變一個狀態(tài)的時候 我需要還是顯示在當(dāng)前頁面 就需要再進入Action 相當(dāng)于再到數(shù)據(jù)庫訪問一次把 我改變的數(shù)據(jù)同個pageVo 顯示到頁面

spring的注解學(xué)習(xí)

@RequestParam("description") String description,
@PathVariable
請求路徑上有個id的變量值,可以通過@PathVariable來獲取  @RequestMapping(value = "/page/{id}", method = RequestMethod.GET)
@autowired 自動配置 不需要寫getter() setter()方法
@Deprecated  過時
@Repository 用在接口前面的類 比如ibits接口類的最前面
@ResponseBody當(dāng)控制器返回頁面不是字符串的時候 比如返回一個json對象用這個注解
@Controller控制器 加在控制器類的最前面
@RequestMapping("/admin/file")
放在類前面是這個路徑下
@RequestMapping(value = "/index.htm", method = RequestMethod.GET)如果這個注解放在方法的前面 表示上面那個路徑的基礎(chǔ)下然后再是這個路勁
@RequestParam(value = "fileId", defaultValue = "1")當(dāng)url傳入?yún)?shù)的時候就可以拿到值
比如@RequestMapping(value = "/update.htm", method = RequestMethod.GET)
public String update(
@RequestParam(value = "fileId", defaultValue = "1") long fileId,
ModelMap modelMap) throws Exception {}

簡單原理:

spring mvc請所有的請求都提交給在web.xml中配置的DispatcherServlet,由它查詢一個或多個HandlerMapping,找到處理請求的Controller,并且將請求提交給這個類。
Controller進行業(yè)務(wù)邏輯處理后,會返回一個ModelAndView
Dispathcher查詢一個或多個 ViewResolver視圖解析器,找到ModelAndView對象指定的視圖對象 ,視圖對象負責(zé)渲染返回給客戶端。
 
2、如何快速學(xué)習(xí)strust2
1 導(dǎo)入struts2.x的相關(guān)jar包到WEB-INF/lib下
2 在項目的src目錄下新建struts.properties或struts.xml
struts.properties和struts.xml具有相同的配置作用,配置項目相關(guān)
3 web.xml加入:

    <filter>   
        <filter-name>ActionContextCleanUp</filter-name>   
        <filter-class>com.opensymphony.webwork.dispatcher.ActionContextCleanUp</filter-class>   
    </filter>   
    <!-- 若有其他相關(guān)的filter 需要加在這個地方-->   
    <!--配置struts2過濾器-->   
    <filter>   
        <filter-name>webwork</filter-name>   
        <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>   
    </filter>  
    <filter-mapping>   
        <filter-name>ActionContextCleanUp</filter-name>   
        <url-pattern>/*</url-pattern>   
    </filter-mapping>   
    <filter-mapping>   
        <filter-name>webwork</filter-name>   
        <url-pattern>/*</url-pattern>   
    </filter-mapping>  

編寫action請求處理類.可以繼承struts2的 ActionSupport也可以不繼承,(不過一般為了方便獲取 request,response以及session 最好自己編寫一個類繼承ActionSupport,并在類中獲取request等,讓請求處理類繼承這個類),然后根據(jù)頁面和struts.xml配置決定請求的處理方法.
例1:
頁面中

    <s:form action="login.action" method="post">   
             <s:textfield key="username" name="user.username"/>   
             <s:password key="password" name="user.password" />   
             <s:submit key="submit" />   
    </s:form>  

strust.xml中

    <action name="login" class="cc.dynasoft.action.LoginAction">   
            <result name="success">/welcome.jspresult>   
            <result name="error">/login.jspresult>   
    </action>  

這時請求會交由LoginAction的默認方法execute來處理,在LoginAaction中有user對象及其set方法,頁面屬性會自動注入到此user對象中,返回字符串[success],匹配struts.xml此action內(nèi)的result值確定調(diào)轉(zhuǎn)的展示頁面
 

例2:

-----頁面

    <s:form action="submit.action">   
        <s:textfield name="msg"label="輸入內(nèi)容"/>    
        <s:submit name="save"value="保存"align="left"method="save"/>   
        <s:submit name="print"value="打印"align="left"method="print"/>    
    </s:form>   

struts.xml

    -----struts.xml:
     
    <action name="submit" class="action.MoreSubmitAction">   
        <result name="save">/result.jsp</result>   
        <result name="print">/result.jsp</result>   
    </action>   

由頁面submit的method方法來指定對應(yīng)的處理方法,方法返回字符串.繼而確定調(diào)轉(zhuǎn)展示頁面
例3:
-----設(shè)置自定義的url后綴,有struts2處理例如struts.action.extension=php.默認為action,即處理所有*.action的請求
-----頁面

    <form  method="post" action="Kinder_add.php"   
        <input type="text" name="kinder.name">   
        <input  type="text"name="kinder.zip">   
        <input type="submit" value="提交">   
    </form>   

-----strust.xml

    <action name="*_*" method="{2}" class="ostar.lg.action.{1}Action">   
        <result name="success">/default.jsp</result>   
    </action>  

這樣的意思是:所有由'_'間隔的請求都會有'_'前面的字符串同名的action類處理,并交給這個類的和'_'后面字符串同名的方法處理[簡化了配置],方法返回字符串繼而確定調(diào)轉(zhuǎn)展示的頁面.(*_*只是一種自定義格式,可任意配置)
B 流程:
1、客戶端初始化一個對服務(wù)器的請求(tomcat);
2、這個請求經(jīng)過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對于 Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin);
3、接著FilterDispatcher被調(diào)用,F(xiàn)ilterDispatcher詢問ActionMapper來決定這個請求是否需要調(diào)用某個 Action;
4、如果ActionMapper決定需要調(diào)用某個Action,F(xiàn)ilterDispatcher把請求的處理交給ActionProxy;
5、ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調(diào)用的Action類;
6、ActionProxy創(chuàng)建一個ActionInvocation的實例。
7、ActionInvocation實例使用命名模式來調(diào)用,在調(diào)用Action的過程前后,涉及到相關(guān)攔截器(Intercepter)的調(diào)用。
8、一旦Action執(zhí)行完畢,ActionInvocation負責(zé)根據(jù)struts.xml中的配置找到對應(yīng)的返回結(jié)果。返回結(jié)果通常是(但不總是,也可能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。
C特性分析:
1 線程模式,每一次請求都會產(chǎn)生一個新的實例處理請求. 多線程環(huán)境沒有數(shù)據(jù)同步問題.
2 引入數(shù)據(jù)的依賴注入
[頁面表單數(shù)據(jù)到action的注入,實例對象的注入,都是通過set注入,需要提供set方法]
3 基于AOP的攔截器,可以在每次請求前后靈活控制
4 配置文件支持表達式,基于約定優(yōu)于配置的話可簡化配置文件
4 內(nèi)置以插件形式支持ajax如dojo,支持多種模板展示jsp、freemarker,Velocity等
3、如何快速學(xué)習(xí)strust1
1 導(dǎo)入struts1.x的jar包到web-inf/lib下面
2 在web-inf目錄下新建struts-config.xml文件,配置struts相關(guān)內(nèi)容
3 web.xml配置加入:
 

    <servlet>   
        <servlet-name>action</servlet-name>   
        <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>   
        <init-param>   
            <param-name>config</param-name>   
            <param-value>/WEB-INF/struts-config.xml</param-value>   
        </init-param>   
        <init-param>   
            <param-name>debug</param-name>   
            <param-value>3</param-value>   
        </init-param>   
        <init-param>   
            <param-name>detail</param-name>   
            <param-value>3</param-value>   
        </init-param>   
        <load-on-startup>0</load-on-startup>   
    </servlet>   
     <servlet-mapping>   
        <servlet-name>action</servlet-name>   
        <url-pattern>*.do</url-pattern>   
    </servlet-mapping>   

  配置隨容器啟動的servlet,并初始化struts的配置文件.設(shè)置由struts處理的請求標(biāo)識
4 編寫action控制類,繼承Action[復(fù)雜情況繼承DispactureAction],同時在struts-config.xml中配置這個控制類action.例如:

    <action   path="/stock"   
          parameter="method"   
          name="stocklogForm"     
          type="com.xuanmu.struts.action.stock.StockAction"   
          scope="request">   
           <forward name="LIST" path="/productsList.jsp" />   
    </action>

當(dāng)截取到請求為stock時就由StockAaction處理.[繼承DispactureAction的話分發(fā)到parameter值對應(yīng)的方法中去], 該方法返回由字符串封裝[LIST]的ActionForward對象,然后再struts-config.xml中的匹配 ,決定返回呈現(xiàn)的頁面
B流程:
1預(yù)備工作:服務(wù)器啟動,Web應(yīng)用啟動時就會加載web.xml初始化actionServlet和記載struts配置文件(struts-config.xml),讀配置信息到內(nèi)存中,供以后action調(diào)用
2(由請求定位action控制類)
用戶通過客戶端向服務(wù)器發(fā)出一個請求,http://localhost:8080/struts_login/login.do
我們已經(jīng)在web.xml配置了所有符合某特定格式的請求都將由struts指定的Servlet來處理。比如:只要是以.do結(jié)尾的請求(*.do)都由 org.apache.struts.action.ActionServlet來對其進行處理.ActionServlet會拿到用戶的請求,并且去分析這個URL,它會截下 /login. 截下來之后,它是為了去struts-config.xml這個配置文件里面找<action>標(biāo)簽path屬性的值等于所截部分的那個 Action.
3(頁面數(shù)據(jù)注入)
找到對應(yīng)的action之后,ActionServlet會把表單提交的數(shù)據(jù)給存放(生成對應(yīng)調(diào)用 set/get方法)到struts-config中相應(yīng)的action標(biāo)簽的name屬性值指定的actionform類中(若有, [actionform的子類,并且在form-bean標(biāo)簽中配置了,若要進行數(shù)據(jù)驗證可以在actionform中覆蓋validate方法,推薦使用js,減輕服務(wù)器負擔(dān)]).同時把actionform和當(dāng)前HttpServletrequest 對象注入到代調(diào)用的action方法中.
4(調(diào)用action的處理方法)
[默認是execute方法可以通過dispactureAction分發(fā)請求給自定義的方法]可以在方法中取得請求附屬的數(shù)據(jù)(若需要),編寫業(yè)務(wù)邏輯代碼處理請求.
5(返回到view層的頁面)
Action的業(yè)務(wù)邏輯方法會返回一個ActionForward對象 ,ActionForward對象根據(jù)此action配置的<forward>匹配name進而調(diào)轉(zhuǎn)到對應(yīng)path的jsp頁面上.
 
表現(xiàn)層常見框架的對比
springmvc和strust2比較
 
1、spring mvc是基于方法的設(shè)計,而sturts是基于類,每次發(fā)一次請求都會實例一個action,每個action都會被注入屬性,而spring基于方法,粒度更細,但要小心把握像在servlet控制數(shù)據(jù)一樣。spring3 mvc是方法級別的攔截,攔截到方法后根據(jù)參數(shù)上的注解把request數(shù)據(jù)注入進去,在spring3 mvc中,一個方法對應(yīng)一個request上下文。而struts2框架是類級別的攔截,每次來了請求就創(chuàng)建一個Action,然后調(diào)用setter getter方法把request中的數(shù)據(jù)注入,struts2實際上是通過setter getter方法與request打交道的,struts2中,一個Action對象對應(yīng)一個request上下文。
 
2、 參數(shù)傳遞struts是在接受參數(shù)的時候,可以用屬性來接受參數(shù),這就說明參數(shù)是讓多個方法共享的。
 
3、 設(shè)計思想上,struts更加符合oop(面向?qū)ο缶幊?的編程思想, spring就比較謹慎,在servlet上擴展。
 
4. intercepter的實現(xiàn)機制,struts有以自己的interceptor機制,spring mvc用的是獨立的AOP方式。這樣導(dǎo)致struts的配置文件量還是比spring mvc大,雖然struts的配置能繼承,所以我覺得論使用上來講,spring mvc使用更加簡潔,開發(fā)效率Spring MVC確實比struts2高。spring mvc是方法級別的攔截,一個方法對應(yīng)一個request上下文,而方法同時又跟一個url對應(yīng),所以說從架構(gòu)本身上spring3 mvc就容易實現(xiàn)restful url。struts2是類級別的攔截,一個類對應(yīng)一個request上下文實現(xiàn)restful url要費勁因為struts2 action的一個方法可以對應(yīng)一個url而其類屬性卻被所有方法共享這也就無法用注解或其他方式標(biāo)識其所屬方法了。spring3 mvc的方法之間基本上獨立的獨享request response數(shù)據(jù)請求數(shù)據(jù)通過參數(shù)獲取處理結(jié)果通過ModelMap交回給框架方法之間不共享變量而struts2搞的就比較亂雖然方法之間也是獨立的但其所有Action變量是共享的這不會影響程序運行卻給我們編碼讀程序時帶來麻煩。
 
5. 另外spring3 mvc的驗證也是一個亮點,支持JSR303處理ajax的請求更是方便,只需一個注解@ResponseBody ,然后直接返回響應(yīng)文本即可。
 
6.springmvc沒有那么多配置,而strust2配置太多了,spring 2.5之后annotation開始簡化之前的xml配置。眾所周知,一個項目或者產(chǎn)品到達一定的建設(shè)程度,如果xml配置文件過多,維護起來確實比較麻煩,spring MVC通過一個spring-config.xml的配置文件配置跳轉(zhuǎn)路徑,在controller簡單@指向即可。從這點上,項目的干凈程度,可維護性不言而喻是struts.xml不能比擬的。
 
7、從設(shè)計實現(xiàn)角度來說,我覺得SpringMVC更加清晰。即使我們?nèi)Ρ萐truts2的原理圖和SpringMVC的類圖,它依然很讓人困惑,遠沒有SpringMVC更加直觀:
 
8、組件化的設(shè)計方案和特定的設(shè)計原則讓SpringMVC形散神聚。
     神 —— SpringMVC總是沿著一條固定的邏輯主線運行
     形 —— SpringMVC卻擁有多種不同的行為模式
      SpringMVC是一個基于組件的開發(fā)框架,組件的不同實現(xiàn)體系構(gòu)成了“形”;組件的邏輯串聯(lián)構(gòu)成了“神”。因此,“形散神不散”: SpringMVC的邏輯主線始終不變,而行為模式卻可以多種多樣。
 
9、springmvc更加靈活,效率高,擴展性更好,有點類似ioc 、aop
 
10、Struts2對于Controller的改造徹底與web容器解耦,更方便單元測試,而擺脫了Servlet束縛,在Controller中徹底杜絕引入HttpServletRequest或者HttpServletResponse這樣的原生Servlet對象,將請求參數(shù)和響應(yīng)數(shù)據(jù)都從響應(yīng)方法中剝離到了Controller中的屬性變量。
 
strust2和strust1對比
1、在Action實現(xiàn)類方面的對比:Struts 1要求Action類繼承一個抽象基類;Struts 1的一個具體問題是使用抽象類編程而不是接口。Struts 2 Action類可以實現(xiàn)一個Action接口,也可以實現(xiàn)其他接口,使可選和定制的服務(wù)成為可能。Struts 2提供一個ActionSupport基類去實現(xiàn)常用的接口。即使Action接口不是必須實現(xiàn)的,只有一個包含execute方法的POJO類都可以用作Struts 2的Action。

2、 線程模式方面的對比:Struts 1 Action是單例模式并且必須是線程安全的,因為僅有Action的一個實例來處理所有的請求。單例策略限制了Struts 1 Action能做的事,并且要在開發(fā)時特別小心。Action資源必須是線程安全的或同步的;Struts 2 Action對象為每一個請求產(chǎn)生一個實例,因此沒有線程安全問題。

3、Servlet依賴方面的對比:Struts 1 Action依賴于Servlet API,因為Struts 1 Action的execute方法中有HttpServletRequest和HttpServletResponse方法。Struts 2 Action不再依賴于Servlet API,從而允許Action脫離Web容器運行,從而降低了測試Action的難度。 當(dāng)然,如果Action需要直接訪問HttpServletRequest和HttpServletResponse參數(shù),Struts 2 Action仍然可以訪問它們。但是,大部分時候,Action都無需直接訪問HttpServetRequest和HttpServletResponse,從而給開發(fā)者更多靈活的選擇。

4、可測性方面的對比:測試Struts 1 Action的一個主要問題是execute方法依賴于Servlet API,這使得Action的測試要依賴于Web容器。為了脫離Web容器測試Struts 1的Action,必須借助于第三方擴展:Struts TestCase,該擴展下包含了系列的Mock對象(模擬了HttpServetRequest和HttpServletResponse對象),從而可以脫離Web容器測試Struts 1的Action類。Struts 2 Action可以通過初始化、設(shè)置屬性、調(diào)用方法來測試。

5、 封裝請求參數(shù)的對比:Struts 1使用ActionForm對象封裝用戶的請求參數(shù),所有的ActionForm必須繼承一個基類:ActionForm。普通的JavaBean不能用作ActionForm,因此,開發(fā)者必須創(chuàng)建大量的ActionForm類封裝用戶請求參數(shù)。雖然Struts 1提供了動態(tài)ActionForm來簡化ActionForm的開發(fā),但依然需要在配置文件中定義ActionForm;Struts 2直接使用Action屬性來封裝用戶請求屬性,避免了開發(fā)者需要大量開發(fā)ActionForm類的煩瑣,實際上,這些屬性還可以是包含子屬性的Rich對象類型。如果開發(fā)者依然懷念Struts 1 ActionForm的模式,Struts 2提供了ModelDriven模式,可以讓開發(fā)者使用單獨的Model對象來封裝用戶請求參數(shù),但該Model對象無需繼承任何Struts 2基類,是一個POJO,從而降低了代碼污染。
6、表達式語言方面的對比:Struts 1整合了JSTL,因此可以使用JSTL表達式語言。這種表達式語言有基本對象圖遍歷,但在對集合和索引屬性的支持上則功能不強;Struts 2可以使用JSTL,但它整合了一種更強大和靈活的表達式語言:OGNL(Object Graph Notation Language),因此,Struts 2下的表達式語言功能更加強大。

7、 — 綁定值到視圖的對比:Struts 1使用標(biāo)準JSP機制把對象綁定到視圖頁面;Struts 2使用“ValueStack”技術(shù),使標(biāo)簽庫能夠訪問值,而不需要把對象和視圖頁面綁定在一起。

8、類型轉(zhuǎn)換的對比:Struts 1 ActionForm 屬性通常都是String類型。Struts 1使用Commons-Beanutils進行類型轉(zhuǎn)換,每個類一個轉(zhuǎn)換器,轉(zhuǎn)換器是不可配置的;Struts 2使用OGNL進行類型轉(zhuǎn)換,支持基本數(shù)據(jù)類型和常用對象之間的轉(zhuǎn)換。

9、 數(shù)據(jù)校驗的對比:Struts 1支持在ActionForm重寫validate方法中手動校驗,或者通過整合Commons alidator框架來完成數(shù)據(jù)校驗。Struts 2支持通過重寫validate方法進行校驗,也支持整合XWork校驗框架進行校驗。

10、 Action執(zhí)行控制的對比:Struts 1支持每一個模塊對應(yīng)一個請求處理(即生命周期的概念),但是模塊中的所有Action必須共享相同的生命周期。Struts 2支持通過攔截器堆棧(Interceptor Stacks)為每一個Action創(chuàng)建不同的生命周期。開發(fā)者可以根據(jù)需要創(chuàng)建相應(yīng)堆棧,從而和不同的Action一起使用。

11、捕獲輸入:Struts1 使用ActionForm對象捕獲輸入。所有的ActionForm必須繼承一個基類。因為其他JavaBean不能用作ActionForm,開發(fā)者經(jīng)常創(chuàng)建多余的類捕獲輸入。動態(tài)Bean(DynaBeans)可以作為創(chuàng)建傳統(tǒng)ActionForm的選擇,但是,開發(fā)者可能是在重新描述(創(chuàng)建)已經(jīng)存在的JavaBean(仍然會導(dǎo)致有冗余的javabean)。Struts 2直接使用Action屬性作為輸入屬性,消除了對第二個輸入對象的需求。輸入屬性可能是有自己(子)屬性的rich對象類型。Action屬性能夠通過 web頁面上的taglibs訪問。Struts2也支持ActionForm模式。rich對象類型,包括業(yè)務(wù)對象,能夠用作輸入/輸出對象。這種 ModelDriven 特性簡化了taglib對POJO輸入對象的引用。

 




作者:chen.yu
深信服三年半工作經(jīng)驗,目前就職游戲廠商,希望能和大家交流和學(xué)習(xí),
微信公眾號:編程入門到禿頭 或掃描下面二維碼
零基礎(chǔ)入門進階人工智能(鏈接)