MVC Struts是一个Java Web MVC开发框架。MVC早在1978年就作为Smalltalk的一种设计模式被提出来了,引用到Web应用中来时:模型Model用于封装与业务逻辑相关的数据和数据处理方法视图View是数据的HTML展现控制器Controller负责响应请求,协调Model和ViewModel,View和Controller的分开,是一种典型的关注点分离的思想,不仅使得代码复用性和组织性更好,使得Web应用的配置性和灵活性更好。MVC开发模式下,Java Web开发会遇到URL路由、模板渲染、表单绑定/提交/验证、Session封装、权限验证、国际化等一系列通用的问题,而MVC框架会将这些通用问题都封装进框架中,你在应用中根据自己的场景进行简单的配置和编码即可,MVC框架就能帮你处理好一切,可以极大地简化代码。
Struts1
Struts工作流程
首先初始化,读取配置(初始化ModuleConfig对象):ActionServlet是struts框架的总控制器,同时它也是一个Servlet,需要在web.xml中配置成自动启动。这样在web应用程序部署到服务器上以后,ActionServlet将自动初始化,它的主要任务就是读取struts的配置文件(struts-config.xml)的配置信息,而struts-config.xml是struts中核心的配置文件,在这个文件中配置了用户请求URL和控制器Action的映射关系,ActionServlet通过这个配置文件把用户的请求发送到对应的控制器中; 并且为不同的struts模块初始化相应的ModuleConfig对象(包括ActionConfig、ControlConfig、FormBeanConfig、ForwardConfig、MessageResourcesConfig)。
public void init() throws ServletException {
// 此处省略了方法前后的异常处理
// 第一阶段,准备阶段
initInternal();
initOther();
initServlet();
// 第二阶段, 默认模块配置解析
getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);
initModuleConfigFactory();
// Initialize modules as needed
ModuleConfig moduleConfig = initModuleConfig("", config);
// 第三阶段,默认模块组件初始化
initModuleMessageResources(moduleConfig);
initModuleDataSources(moduleConfig);
initModulePlugIns(moduleConfig);
moduleConfig.freeze();
// 第四阶段, 自定义模块初始化
Enumeration names = getServletConfig().getInitParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
if (!name.startsWith("config/")) {
continue;
}
String prefix = name.substring(6);
moduleConfig = initModuleConfig
(prefix, getServletConfig().getInitParameter(name));
initModuleMessageResources(moduleConfig);
initModuleDataSources(moduleConfig);
initModulePlugIns(moduleConfig);
moduleConfig.freeze();
}
// 第五阶段,收尾阶段
this.initModulePrefixes(this.getServletContext());
this.destroyConfigDigester();
}
<struts-config>
<form-beans>
<form-bean name="registerForm" type="cn.liayun.web.formbean.RegisterFormBean"></form-bean>
</form-beans>
<!-- Struts1在调用RegisterAction的时候,它会把所有<action>...</action>中的配置信息封装到ActionMapping对象中 -->
<action-mappings> <!-- Struts1收到register请求的时候,将把请求中的所有数据封装到registerForm对象中 -->
<action path="/register"
name="registerForm"
type="cn.liayun.web.action.RegisterAction"
scope="request"
attribute="liayun"
parameter="method">
<forward name="message" path="message.jsp" />
</action>
<action path="/registerUI" forward="/register.jsp"></action>
<action path="/error" unknown="true" forward="/WEB-INF/jsp/error.jsp"></action>
</action-mappings>
<!-- 配置请求处理器(来处理请求),Struts1.2采用的请求处理器是RequestProcessor -->
<controller processorClass="org.apache.struts.action.RequestProcessor"></controller>
</struts-config>
在struts web应用程序中,当web应用程序启动的时候,就会初始化ActionServlet在初始化ActionServlet的时候会加载struts-config.xml配置文件,在加载成功后会把这些URL和控制器映射关系存放在ActionMapping对象或者其他对象中。当ActionServlet接收到用户请求的时候,就会按照下面的流程对用户请求进行处理。
image.png
(1)ActionServlet接收到用户的请求后,会根据请求URL寻找匹配的ActionMapping对象,如果匹配失败,说明用户请求的URL路径信息有误,所以返回请求路径无效的信息,当找到匹配的ActionMapping的时候,进入到下一步。
(2)当ActionServlet找到匹配的ActionMapping对象的时候,会根据ActionMapping中的映射信息判断对应的ActionForm对象是否存在,如果不存在对应的ActionForm对象就创建一个新的ActionForm对应,并把用户提交的表单信息保存到这个ActionForm对象中。
//actionform示例
public class AddStudentForm extends ActionForm {
private String name;
private String major;
private float score;
private Date birth;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
public float getScore() {
return score;
}
public void setScore(float score) {
this.score = score;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
}
(3)在struts-config.xml中这个配置文件,可以配置表单是否需要验证,如果需要验证,就调用ActionForm中的validate()方法对用户输入的表单进行验证。
(4)如果ActionForm的validate()方法返回了ActionErrors对象,则表明验证失败,ActionServlet把这个页面返回到用户输入的界面,提示用户重新输入。如果方法的返回值为null,就表明验证已经通过,可以进入下一步处理。
(5)ActionServlet可以根据ActionMapping对象查找用户请求转发给哪个控制器Action,如果对应的Action对象不存在,就创建这个对象,并调用这个Action的excute()方法。具体 Action 类的功能一般都在 execute方法中完成。
//execute方法示例
AddStudentForm addStu = (AddStudentForm)form;
IStudentDAO stuDAO = new StudentDAO();
boolean successful = false;
successful = stuDAO.addStudent(addStu);
if(successful)
return mapping.findForward("addSuccess");
else
return mapping.findForward("addFailure");
(6)业务逻辑控制器Action的execute()方法就会返回一个ActionForward对象,ActionServlet把控制器处理的结果转发到ActionForward对象指定的JSP页面。
action配置示例
<form-bean name="addStuForm" type="com.yxb.struts.AddStudentForm"></form-bean>
<action path="/addStu.do"
type="com.yxb.struts.AddStudentAction"
name="addStuForm">
<forward name="addSuccess" path="/add_success.jsp"></forward>
<forward name="addFailure" path="/add_failure.jsp"></forward>
</action>
(7)ActionForward对象指定的JSP页面根据返回的处理结果,用合适形式把服务器处理的结果展示给用户,到这里为止,一个客户请求的整个过程完毕。
Struts1 MVC结构流程总结:
- 整个struts的开发满足了标准的MVC处理结构,结构严谨,但是这种实现方式也存在一定的历史局限性;也在初期的ActionForm设计上出现了设计失误;
- 随着项目开发的进行,在struts开发里面一定会存在多个Action,但是每一个Action都必须有一个与之对应的ActionForm绑定,那么开发的代码量非常大。
- Actionform需要编写验证操作,如果分开写那么所面临的问题是百分之九十的代码是重复的;所有要使用的Action和ActionForm需要在struts-config.xml里进行定义,如果涉及工程量大的项目,配置文件一大,在做修改的时候就有可能出现错乱;
网友评论