昨天写了那个[struts工作流程分析] 感觉有点乱,今天整理了一下,当然不是我自己研究出来的,我喜欢看完技术资料后用自己所理解的意思去表述一遍,当然我有时也会原文转来。今天又增加了一个栏目《系统漏洞》,这里的漏洞就更不可能是我发现的了,都是直接转来的。博客是不是必须纯原创我才不去管它,我只关注和学习我所感兴趣的。
struts的工作原理可分为如下8步。
1.读取配置(初始化ModuleConfig对象)
Struts框架总控制器(ActionServlet)是一个Servlet,在web.xml中被配置成一个自动启动的Servlet。读取配置文件struts-config.xml的配置信息,为不同的Struts模块初始化相应的ModuleConfig对象。
2.用户请求
用户提交表单或调用URL向WEB应用程序服务器提交一个请求,请求的数据用HTTP协议上传给WEB服务器。
3.填充FormBean
(*.do请求)从ActionConfig中找出对应该请求的Action子类,如有对应的Action且这个Action又一个相应的ActionForm,ActionForm被实例化并用HTTP请求的数据填充其属性,并保存在ServletContext中,这样他们就可以被其它Action对象或JSP调用。如果没有对应的Action,控制器则直接转发给JSP或静态页面。
4.派发请求
控制器根据配置信息ActionConfig将请求派发到具体的Action,相应的FormBean一并传给这个Action的execute()方法。
5.处理业务
Action一般只包含一个execute方法,它负责执行相应的业务逻辑。执行完毕后返回一个ActionFoward对象,控制器通过该ActionFoward对象来进行转发工作。
6.返回响应
Action根据业务处理的不同结果返回一个响应对象给总控制器,该目标响应对相对应一个具体的JSP页面或另一个Action。
7.查找响应
总控制器根据业务功能Action返回的目标响应对象找到对应的资源对象,通常是一个具体的JSP页面。
8.响应用户
JSP将结果展现给用户。
技术关键在于学习其原理,而不是浅浅淡淡的会用,免得别人问起的时候什么也不知道,尤其是在面试时!
首先页面上的数据请求被发送到服务器,此时的请求先进入到前端控制器(ActionServlet)。ActionServlet再将请求转发给后端控制器(Action),在转发中顺便送了一份礼物form(ActionForm),在Action中对form中的数据做实际的处理操作并返回一份礼物forward(ActionForward)给ActionServlet,ActionServlet收到这份礼物后根据其中的关键字从struts配置文件Struts-config.xml中获取具体的跳转页。
那么ActionServlet是怎么知道该找哪个后端控制器呢?又是怎么知道返回的ActionForward具体是什么呢?为了回答这个问题,我们参考一个用Struts做的登陆程序。
登陆表单代码:
- <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>struts工作流程分析</title>
- </head>
- <body>
- <form action="login.do" method="POST">
- 用户名:<input type="text" name="userName"><br/>
- 密码:<input type="password" name="userPwd"><br/>
- <input type="submit" value="登录">
- </form>
- </body>
- </html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>struts工作流程分析</title> </head> <body> <form action="login.do" method="POST"> 用户名:<input type="text" name="userName"><br/> 密码:<input type="password" name="userPwd"><br/> <input type="submit" value="登录"> </form> </body></html>
LoginAction代码:
- package cn.ineeke.action;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.apache.struts.action.Action;
- import org.apache.struts.action.ActionForm;
- import org.apache.struts.action.ActionForward;
- import org.apache.struts.action.ActionMapping;
-
- import cn.ineeke.form.LoginForm;
- *作者:Neeke
- *BLOG:http://www.ineeke.com
- */
- public class LoginAction extends Action {
-
- @Override
- public ActionForward execute(ActionMapping mapping, ActionForm form,
- HttpServletRequest request, HttpServletResponse response)
- throws Exception {
- LoginForm loginForm = (LoginForm)form;
- String forwardName = "failure";
- if(loginForm.getUserName().equals("neeke") && loginForm.getUserPwd().equals("123456")){
- forwardName = "success";
- }
- return mapping.findForward(forwardName);
- }
-
- }
package cn.ineeke.action;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts.action.Action;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;import cn.ineeke.form.LoginForm;/** *作者:Neeke *BLOG:http://www.ineeke.com */public class LoginAction extends Action { @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LoginForm loginFor
m = (LoginForm)form; String forwardName = "failure"; if(loginForm.getUserName().equals("neeke") && loginForm.getUserPwd().equals("123456")){ forwardName = "success"; } return mapping.findForward(forwardName); }}
LoginForm代码:
- package cn.ineeke.form;
-
- import org.apache.struts.action.ActionForm;
-
- public class LoginForm extends ActionForm {
- private String userName = null;
- private String userPwd = null;
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- public String getUserPwd() {
- return userPwd;
- }
- public void setUserPwd(String userPwd) {
- this.userPwd = userPwd;
- }
- }
package cn.ineeke.form;import org.apache.struts.action.ActionForm;public class LoginForm extends ActionForm { private String userName = null; private String userPwd = null; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPwd() { return userPwd; } public void setUserPwd(String userPwd) { this.userPwd = userPwd; }}
Struts-config.xml文件:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd">
-
- <struts-config>
- <form-beans>
- <form-bean name="loginForm" type="cn.ineeke.form.LoginForm"></form-bean>
- </form-beans>
- <action-mappings>
- <action path="/login" type="cn.ineeke.action.LoginAction" name="loginForm">
- <forward name="success" path="/success.jsp"></forward>
- <forward name="failure" path="/failure.jsp"></forward>
- </action>
- </action-mappings>
- <message-resources parameter="cn.ineeke.struts.ApplicationResources" />
- </struts-config>
-
<?xml version="1.
0" encoding="UTF-8"?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd"><struts-config> <form-beans> <form-bean name="loginForm" type="cn.ineeke.form.LoginForm"></form-bean> </form-beans> <action-mappings> <action path="/login" type="cn.ineeke.action.LoginAction" name="loginForm"> <forward name="success" path="/success.jsp"></forward> <forward name="failure" path="/failure.jsp"></forward> </action> </action-mappings> <message-resources parameter="cn.ineeke.struts.ApplicationResources" /></struts-config>
当我们的表单提交给login.do的时候,ActionServlet就会去读取Struts-config.xml文件并根据<action path="/login" type="cn.ineeke.action.LoginAction" name="loginForm">中的type属性找到具体的后端控制器LoginAction,与此同时又根据name属性找到<form-bean name="loginForm" type="cn.ineeke.form.LoginForm"></form-bean>并将表单中的数据存储在LoginForm的实例中(这个实例就是前端控制器送给后端控制器的礼物了),在LoginAction的execute方法中进行数据处理并返回一个ActionForward对象(回赠一份礼物)给ActionServlet。最后ActionServlet再根据这份礼物的关键字在
<forward name="success" path="/success.jsp"></forward>
<forward name="failure" path="/failure.jsp"></forward>
中进行查找,并跳转到相应的path。