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中的预先配置来加载对应视图的。