Struts2与Struts1的区别

Struts1于2001年6月发布,是第一个发布的MVC框架。Struts1通过核心 控制器ActionServlet来接受用户所有的请求,并将请求转发给业务逻辑控制器。

由业务逻辑控制器处理用户请求,用户请求处理完成后,业务逻辑控制器会根据业务逻辑将处理结果通过JSP的方式返回给用户。

在struts1中,业务逻辑控制器为Action和ActionForm。ActionForm是一个普通的Java对象,它需要为用户提交的每一个参数提供一个对应的属性,并为每个属性提供setter和getter方法。Action中包含一个execute方法,在该方法中获取ActionForm的实例,通过调用业务逻辑组件处理用户请求,并根据返回结果调用不同的页面来显示数据。

在应用程序中,开发人员需要通过继承Action和ActionForm来自行创建业务逻辑控制器。在Struts1中,还需要一个文件Struts-config.xml配置文件,用于配置Action/ActionForm以及逻辑视图和视图资源之间的映射关系。

下面是一个登录的业务逻辑控制器Action及相应的ActionForm,ActionForm用来封装用户请求的信息:[code]public class LoginAction extends Action() {
public ActionForwardexecute(ActionMappingmapping,ActionFormform,
HttpServletRequest request,HttpServletResponse response){

    //获取ActionForm的实例
    LoginForm loginForm = (LoginForm)form;

    //获取用户请求
    String name = loginForm.getUname();
    String password =loginForm.getUpassword();

   //这里创建一个业务逻辑组件对象,用于验证用户数据的有效性
   ........

   //调用业务逻辑组件的判断功能来判断用户是否合法
   if(用户是否合法) {
       //合法
       request.setAttribute("login","true");
       return  mapping.findForward("success");
   }else{
       //不合法
      return mapping.findForward("error");
     }
}

}

public class LoginForm extends ActionForm{
private String uname;
private String upassword;

 //获得uname的值
 public String getUname(){
     return  uname;
  }

 //设置uname的值
 public void setUname(String uname) {
      this.uname= uname ;
  }

 //获取upassword的值
 public  String getUpassword() {
     return upassword;
  }

 //设置upassword的值
 public  void setUpassword(String upassword) {
     this.upassword= upassword;
  }

}[/code]接下来需要在struts-config.xml文件中进行配置,指定ActionForm和Action的实现类以及定义逻辑视图,使得执行LoginAction类方法execute时,根据返回的字符串值来显示对应的页面。

从上面的业务逻辑控制器来看,Struts1有以下缺陷:

1.业务逻辑控制器Action与Servlet API耦合度高。
代码中的execute方法需要4个参数,分别是ActionMapping,ActionForm,HttpServletRequest,HttpServletResponse。其中HttpServletRequset和HttpServletResponse属于Servlet API,这样使得业务逻辑控制器Action与Servlet API的耦合度高。

2.代码依赖于Struts 1 API,难以扩展
Struts1中的业务逻辑组件必须继承Struts 1的Action基类和ActionForm。业务逻辑组件Action的execute方法包含大量的Struts 1 API,如ActionMapping,ActionForm以及ActionForward。这使得项目如果要重构时,这些Action就完全失去了利用价值。

还有几点,如ActionForm的使用可能导致有冗余的JavaBean,Struts 1只能使用单一JSP作为表示层,使用JSTL EL,对集合和索引属性的支持很弱等,读者可以自行去了解。

而在Struts2中,大大简化和优化了以上过程。它与Struts1的体系结构的差别很大,可以说是没什么太大的联系。Struts2主要吸收了WebWork的设计思想,它以WebWork为核心,分离了业务逻辑控制器和Servet API,使得Struts2框架结构更清晰,使用更方便灵活。开发人员要完成上面的业务逻辑控制器,只需要建立控制器类Action,在“struts.xml”(在Struts 1中为“struts-config.xml”)文件中配置该Action即可。

Struts2中取消了ActionForm,而是在Action中封装用户的请求参数,还包含一个execute方法用来调用业务逻辑组件进行判断,并通过返回字符串,Struts 2跳转到指定的视图资源。下面为使用Struts 2实现的LoginAction类:[code]public class LoginAction() {
private String uname;
private String upassword;

 //获得uname的值
 public String getUname(){
     return uname;
  }

 //设置uname的值
 public  void setUname(String uname) {
      this.uname= uname ;
  }

 //获取upassword的值
 public String getUpassword() {
      returnupassword;
  }

 //设置upassword的值
 public void  setUpassword(String upassword) {
      this.upassword= upassword;
  }


 public String execute() throws Exception{

 //这里创建一个业务逻辑组件对象,用于验证用户数据的有效性
  .......

 //调用业务逻辑组件的判断功能来判断用户是否合法
     if(用户是否合法) {
         //合法
        ServletActionContext.getRequest.setAttribute("login","true");
        return  "success";
      }else{
        //不合法
        return  "error";
      }
  }

}[/code]从上面的LoginAction类可以看出,控制器不需要继承Action父类,也无需实现任何接口,是一个普通的POJO类(Plain Old Java Objects,简单的Java对象,只有一些属性及其setter,getter方法的类)。

而且Struts 2返回的是一个普通的字符串,而不是一个ActionForm。这样就使得Action类和Servlet API完全分离了,也不需要依赖于Struts API,保持高度的内聚,使得在今后的扩展和重构更容易。

最后给出Struts 2的体系结构图:

在第6步中,调用Action后,是根据在Struts.xml中的预先配置来加载对应视图的。