快速学习使用springmvc、strust2、strust1以及它们的对比

1、如何快速学习springmvc
       首先,我们需要在复制spring相关的jar包到web-inf/lib里面去,然后在web.xml里面加入以下代码,相当于springmvc里面的servlet,这里只说明了一些常见的用法,如果要了解springmvc里面的控制器这些详细原理可以到网上再去找好详细学习。

    <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配置文件中加入外部属性文件,当然也可以指定外部文件的编码 -->
        <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" /><!--可为空,方便实现自已的依据扩展名来选择视图解释类的逻辑 -->
            <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结束,如果是用的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 {
                // 获得数据
                Category category = categoryService.getCategoryById(categoryId);
                // 获取当前目录下的所有课程
                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 {
     
        /**
         * 跳转到关于我们页面
         *
         * @param modelMap
         * @param request
         * @return
         */
        @RequestMapping(value = "/about.htm", method = RequestMethod.GET)
        public String about(ModelMap modelMap, HttpServletRequest request) {
            return "/about/about";
        }
     
        /**
         * 跳转到服务协议页面
         *
         * @param modelMap
         * @param request
         * @return
         */
        @RequestMapping(value = "/service.htm", method = RequestMethod.GET)
        public String service(ModelMap modelMap, HttpServletRequest request) {
            return "/about/service";
        }
     
        /**
         * 跳转到投诉举报页面
         *
         * @param modelMap
         * @param request
         * @return
         */
        @RequestMapping(value = "/complain.htm", method = RequestMethod.GET)
        public String complain(ModelMap modelMap, HttpServletRequest request) {
            return "/about/complain";
        }
     
        /**
         * 跳转到版权声明页面
         *
         * @param modelMap
         * @param request
         * @return
         */
        @RequestMapping(value = "/copyright.htm", method = RequestMethod.GET)
        public String copyright(ModelMap modelMap, HttpServletRequest request) {
            return "/about/copyright";
        }
     
        /**
         * 跳转到联系我们页面
         *
         * @param modelMap
         * @param request
         * @return
         */
        @RequestMapping(value = "/connect.htm", method = RequestMethod.GET)
        public String connect(ModelMap modelMap, HttpServletRequest request) {
            return "/about/connect";
        }
     
    }

下面是使用springmvc的经验:

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

return "redirect:/admin/comment/page.htm";一般当我改变一个状态的时候 我需要还是显示在当前页面 就需要再进入Action 相当于再到数据库访问一次把 我改变的数据同个pageVo 显示到页面

spring的注解学习

@RequestParam("description") String description,
@PathVariable
请求路径上有个id的变量值,可以通过@PathVariable来获取  @RequestMapping(value = "/page/{id}", method = RequestMethod.GET)
@autowired 自动配置 不需要写getter() setter()方法
@Deprecated  过时
@Repository 用在接口前面的类 比如ibits接口类的最前面
@ResponseBody当控制器返回页面不是字符串的时候 比如返回一个json对象用这个注解
@Controller控制器 加在控制器类的最前面
@RequestMapping("/admin/file")
放在类前面是这个路径下
@RequestMapping(value = "/index.htm", method = RequestMethod.GET)如果这个注解放在方法的前面 表示上面那个路径的基础下然后再是这个路劲
@RequestParam(value = "fileId", defaultValue = "1")当url传入参数的时候就可以拿到值
比如@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进行业务逻辑处理后,会返回一个ModelAndView
Dispathcher查询一个或多个 ViewResolver视图解析器,找到ModelAndView对象指定的视图对象 ,视图对象负责渲染返回给客户端。
 
2、如何快速学习strust2
1 导入struts2.x的相关jar包到WEB-INF/lib下
2 在项目的src目录下新建struts.properties或struts.xml
struts.properties和struts.xml具有相同的配置作用,配置项目相关
3 web.xml加入:

    <filter>   
        <filter-name>ActionContextCleanUp</filter-name>   
        <filter-class>com.opensymphony.webwork.dispatcher.ActionContextCleanUp</filter-class>   
    </filter>   
    <!-- 若有其他相关的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等,让请求处理类继承这个类),然后根据页面和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内的result值确定调转的展示页面
 

例2:

-----页面

    <s:form action="submit.action">   
        <s:textfield name="msg"label="输入内容"/>    
        <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方法来指定对应的处理方法,方法返回字符串.继而确定调转展示页面
例3:
-----设置自定义的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类处理,并交给这个类的和'_'后面字符串同名的方法处理[简化了配置],方法返回字符串继而确定调转展示的页面.(*_*只是一种自定义格式,可任意配置)
B 流程:
1、客户端初始化一个对服务器的请求(tomcat);
2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于 Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin);
3、接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个 Action;
4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy;
5、ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类;
6、ActionProxy创建一个ActionInvocation的实例。
7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。
C特性分析:
1 线程模式,每一次请求都会产生一个新的实例处理请求. 多线程环境没有数据同步问题.
2 引入数据的依赖注入
[页面表单数据到action的注入,实例对象的注入,都是通过set注入,需要提供set方法]
3 基于AOP的拦截器,可以在每次请求前后灵活控制
4 配置文件支持表达式,基于约定优于配置的话可简化配置文件
4 内置以插件形式支持ajax如dojo,支持多种模板展示jsp、freemarker,Velocity等
3、如何快速学习strust1
1 导入struts1.x的jar包到web-inf/lib下面
2 在web-inf目录下新建struts-config.xml文件,配置struts相关内容
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的配置文件.设置由struts处理的请求标识
4 编写action控制类,继承Action[复杂情况继承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>

当截取到请求为stock时就由StockAaction处理.[继承DispactureAction的话分发到parameter值对应的方法中去], 该方法返回由字符串封装[LIST]的ActionForward对象,然后再struts-config.xml中的匹配 ,决定返回呈现的页面
B流程:
1预备工作:服务器启动,Web应用启动时就会加载web.xml初始化actionServlet和记载struts配置文件(struts-config.xml),读配置信息到内存中,供以后action调用
2(由请求定位action控制类)
用户通过客户端向服务器发出一个请求,http://localhost:8080/struts_login/login.do
我们已经在web.xml配置了所有符合某特定格式的请求都将由struts指定的Servlet来处理。比如:只要是以.do结尾的请求(*.do)都由 org.apache.struts.action.ActionServlet来对其进行处理.ActionServlet会拿到用户的请求,并且去分析这个URL,它会截下 /login. 截下来之后,它是为了去struts-config.xml这个配置文件里面找<action>标签path属性的值等于所截部分的那个 Action.
3(页面数据注入)
找到对应的action之后,ActionServlet会把表单提交的数据给存放(生成对应调用 set/get方法)到struts-config中相应的action标签的name属性值指定的actionform类中(若有, [actionform的子类,并且在form-bean标签中配置了,若要进行数据验证可以在actionform中覆盖validate方法,推荐使用js,减轻服务器负担]).同时把actionform和当前HttpServletrequest 对象注入到代调用的action方法中.
4(调用action的处理方法)
[默认是execute方法可以通过dispactureAction分发请求给自定义的方法]可以在方法中取得请求附属的数据(若需要),编写业务逻辑代码处理请求.
5(返回到view层的页面)
Action的业务逻辑方法会返回一个ActionForward对象 ,ActionForward对象根据此action配置的<forward>匹配name进而调转到对应path的jsp页面上.
 
表现层常见框架的对比
springmvc和strust2比较
 
1、spring mvc是基于方法的设计,而sturts是基于类,每次发一次请求都会实例一个action,每个action都会被注入属性,而spring基于方法,粒度更细,但要小心把握像在servlet控制数据一样。spring3 mvc是方法级别的拦截,拦截到方法后根据参数上的注解把request数据注入进去,在spring3 mvc中,一个方法对应一个request上下文。而struts2框架是类级别的拦截,每次来了请求就创建一个Action,然后调用setter getter方法把request中的数据注入,struts2实际上是通过setter getter方法与request打交道的,struts2中,一个Action对象对应一个request上下文。
 
2、 参数传递struts是在接受参数的时候,可以用属性来接受参数,这就说明参数是让多个方法共享的。
 
3、 设计思想上,struts更加符合oop(面向对象编程)的编程思想, spring就比较谨慎,在servlet上扩展。
 
4. intercepter的实现机制,struts有以自己的interceptor机制,spring mvc用的是独立的AOP方式。这样导致struts的配置文件量还是比spring mvc大,虽然struts的配置能继承,所以我觉得论使用上来讲,spring mvc使用更加简洁,开发效率Spring MVC确实比struts2高。spring mvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上spring3 mvc就容易实现restful url。struts2是类级别的拦截,一个类对应一个request上下文实现restful url要费劲因为struts2 action的一个方法可以对应一个url而其类属性却被所有方法共享这也就无法用注解或其他方式标识其所属方法了。spring3 mvc的方法之间基本上独立的独享request response数据请求数据通过参数获取处理结果通过ModelMap交回给框架方法之间不共享变量而struts2搞的就比较乱虽然方法之间也是独立的但其所有Action变量是共享的这不会影响程序运行却给我们编码读程序时带来麻烦。
 
5. 另外spring3 mvc的验证也是一个亮点,支持JSR303处理ajax的请求更是方便,只需一个注解@ResponseBody ,然后直接返回响应文本即可。
 
6.springmvc没有那么多配置,而strust2配置太多了,spring 2.5之后annotation开始简化之前的xml配置。众所周知,一个项目或者产品到达一定的建设程度,如果xml配置文件过多,维护起来确实比较麻烦,spring MVC通过一个spring-config.xml的配置文件配置跳转路径,在controller简单@指向即可。从这点上,项目的干净程度,可维护性不言而喻是struts.xml不能比拟的。
 
7、从设计实现角度来说,我觉得SpringMVC更加清晰。即使我们去对比Struts2的原理图和SpringMVC的类图,它依然很让人困惑,远没有SpringMVC更加直观:
 
8、组件化的设计方案和特定的设计原则让SpringMVC形散神聚。
     神 —— SpringMVC总是沿着一条固定的逻辑主线运行
     形 —— SpringMVC却拥有多种不同的行为模式
      SpringMVC是一个基于组件的开发框架,组件的不同实现体系构成了“形”;组件的逻辑串联构成了“神”。因此,“形散神不散”: SpringMVC的逻辑主线始终不变,而行为模式却可以多种多样。
 
9、springmvc更加灵活,效率高,扩展性更好,有点类似ioc 、aop
 
10、Struts2对于Controller的改造彻底与web容器解耦,更方便单元测试,而摆脱了Servlet束缚,在Controller中彻底杜绝引入HttpServletRequest或者HttpServletResponse这样的原生Servlet对象,将请求参数和响应数据都从响应方法中剥离到了Controller中的属性变量。
 
strust2和strust1对比
1、在Action实现类方面的对比:Struts 1要求Action类继承一个抽象基类;Struts 1的一个具体问题是使用抽象类编程而不是接口。Struts 2 Action类可以实现一个Action接口,也可以实现其他接口,使可选和定制的服务成为可能。Struts 2提供一个ActionSupport基类去实现常用的接口。即使Action接口不是必须实现的,只有一个包含execute方法的POJO类都可以用作Struts 2的Action。

2、 线程模式方面的对比:Struts 1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts 1 Action能做的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的;Struts 2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。

3、Servlet依赖方面的对比:Struts 1 Action依赖于Servlet API,因为Struts 1 Action的execute方法中有HttpServletRequest和HttpServletResponse方法。Struts 2 Action不再依赖于Servlet API,从而允许Action脱离Web容器运行,从而降低了测试Action的难度。 当然,如果Action需要直接访问HttpServletRequest和HttpServletResponse参数,Struts 2 Action仍然可以访问它们。但是,大部分时候,Action都无需直接访问HttpServetRequest和HttpServletResponse,从而给开发者更多灵活的选择。

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可以通过初始化、设置属性、调用方法来测试。

5、 封装请求参数的对比:Struts 1使用ActionForm对象封装用户的请求参数,所有的ActionForm必须继承一个基类:ActionForm。普通的JavaBean不能用作ActionForm,因此,开发者必须创建大量的ActionForm类封装用户请求参数。虽然Struts 1提供了动态ActionForm来简化ActionForm的开发,但依然需要在配置文件中定义ActionForm;Struts 2直接使用Action属性来封装用户请求属性,避免了开发者需要大量开发ActionForm类的烦琐,实际上,这些属性还可以是包含子属性的Rich对象类型。如果开发者依然怀念Struts 1 ActionForm的模式,Struts 2提供了ModelDriven模式,可以让开发者使用单独的Model对象来封装用户请求参数,但该Model对象无需继承任何Struts 2基类,是一个POJO,从而降低了代码污染。
6、表达式语言方面的对比:Struts 1整合了JSTL,因此可以使用JSTL表达式语言。这种表达式语言有基本对象图遍历,但在对集合和索引属性的支持上则功能不强;Struts 2可以使用JSTL,但它整合了一种更强大和灵活的表达式语言:OGNL(Object Graph Notation Language),因此,Struts 2下的表达式语言功能更加强大。

7、 — 绑定值到视图的对比:Struts 1使用标准JSP机制把对象绑定到视图页面;Struts 2使用“ValueStack”技术,使标签库能够访问值,而不需要把对象和视图页面绑定在一起。

8、类型转换的对比:Struts 1 ActionForm 属性通常都是String类型。Struts 1使用Commons-Beanutils进行类型转换,每个类一个转换器,转换器是不可配置的;Struts 2使用OGNL进行类型转换,支持基本数据类型和常用对象之间的转换。

9、 数据校验的对比:Struts 1支持在ActionForm重写validate方法中手动校验,或者通过整合Commons alidator框架来完成数据校验。Struts 2支持通过重写validate方法进行校验,也支持整合XWork校验框架进行校验。

10、 Action执行控制的对比:Struts 1支持每一个模块对应一个请求处理(即生命周期的概念),但是模块中的所有Action必须共享相同的生命周期。Struts 2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。开发者可以根据需要创建相应堆栈,从而和不同的Action一起使用。

11、捕获输入:Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存在的JavaBean(仍然会导致有冗余的javabean)。Struts 2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过 web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种 ModelDriven 特性简化了taglib对POJO输入对象的引用。

 




作者:chen.yu
深信服三年半工作经验,目前就职游戏厂商,希望能和大家交流和学习,
微信公众号:编程入门到秃头 或扫描下面二维码
零基础入门进阶人工智能(链接)