Struts中请求是如何被处理的
ActionServlet是Struts框架里唯一一个Servlet,它负责处理所有请求。它无论何时收到一个请求,都会首先试着为现有请求找到一个 子应用。一旦子应用被找到,它会为其生成一个RequestProcessor对象,并调用传入HttpServletRequest和 HttpServletResponse为参数的process()方法。
大部分请处理都是在 RequestProcessor.process()发生的。Process()方法是以模板方法(Template Method)的设计模式来实现的,其中有完成request处理的每个步骤的方法;所有这些方法都从process()方法顺序调用。例如,寻找当前请 求的ActionForm类和检查当前用户是否有权限执行action mapping都有几个单独的方法。这给我们提供了极大的弹性空间。Struts的RequestProcessor对每个请求处理步骤都提供了默认的实 现方法。这意味着,你可以重写你感兴趣的方法,而其余剩下的保留默认实现。例如,Struts默认调用request.isUserInRole()检查 用户是否有权限执行当前的ActionMapping,但如果你需要从数据库中查找,那么你要做的就是重写processRoles()方法,并根据用户 角色返回true 或 false。
首先我们看一下process()方法的默认实现方式,然后我将解释RequestProcessor类里的每个默认的方法,以便你决定要修改请求处理的哪一部分。
1、processMultipart(): 在这个方法中,Struts读取request以找出contentType是否为 multipart/form-data。假如是,则解析并将其打包成一个实现HttpServletRequest的包。当你成生一个放置数据的 HTML FORM时,request的contentType默认是application/x-www-form-urlencoded。但是如果你的form 的input类型是FILE-type允许用户上载文件,那么你必须把form的contentType改为multipart/form-data。如 这样做,你永远不能通过HttpServletRequest的getParameter()来读取用户提交的form值;你必须以 InputStream的形式读取request,然后解析它得到值。
2、processPath(): 在这个方法中,Struts将读取request的URI以判断用来得到ActionMapping元素的路径。
3、processLocale(): 在这个方法中,Struts将得到当前request的Locale;Locale假如被配置,将作为 org.apache.struts.action.LOCALE属性的值被存入HttpSession。这个方法的附作用是HttpSession会被 创建。假如你不想此事发生,可将在struts-config.xml 文件里ControllerConfig的local属性设置为false,如下:
7、processMapping():这个方法会利用path信息找到ActionMapping对象。ActionMapping对象在struts-config.xml file文件里表示为<action>
CodeActionMapping元素包含了如Action类的名称及在请求中用到的ActionForm的信息,另外还有配置在当前ActionMapping的里的ActionForwards信息。
8、processRoles(): Struts的web 应用安全提供了一个认证机制。这就是说,一旦用户登录到容器,Struts的processRoles()方法通过调用request.isUserInRole()可以检查他是否有权限执行给定的ActionMapping。
9、processActionForm():每个ActionMapping都有一个与它关联的ActionForm类。struts在处理ActionMapping时,他会从<action>里name属性找到相关的ActionForm类的值。
Code在这个例子里,首先会检查org.apache.struts.action.DynaActionForm类的对象是否在request 范围内。如是,则使用它,否则创建一个新的对象并在request范围内设置它。
10、processPopulate()::在这个方法里,Struts将匹配的request parameters值填入ActionForm类的实例变量中。
11、processValidate():Struts将调用ActionForm的validate()方法。假如validate()返回ActionErrors,Struts将用户转到由<action>里的input属性标示的页面。
12、processForward() and processInclude():在这两个方法里,Struts检查<action>元素的forward和include属性的值,假如有配置,则把forward和include 请求放在配置的页面内。
13、processActionCreate():这个方法从<action>的type属性得到Action类名,并创建返回它的实例。在这里例子中struts将创建一个com.sample.NewContactAction类的实例。
14、processActionPerform():这个方法调用Action 类的execute()方法,其中有你写入的业务逻辑。
15、processForwardConfig():Action类的execute()将会返回一个ActionForward类型的对象,指出哪一页面将展示给用户。因此Struts将为这个页面创建RequestDispatchet,然后再调用RequestDispatcher.forward()方法。
以 上列出的方法解释了RequestProcessor在请求处理的每步默认实现及各个步骤执行的顺序。正如你所见,RequestProcessor很有 弹性,它允许你通过设置<controller>里的属性来配置它。例如,假如你的应用将生成XML内容而不是HTML,你可以通过设置 controller的某个属性来通知Struts。
大部分请处理都是在 RequestProcessor.process()发生的。Process()方法是以模板方法(Template Method)的设计模式来实现的,其中有完成request处理的每个步骤的方法;所有这些方法都从process()方法顺序调用。例如,寻找当前请 求的ActionForm类和检查当前用户是否有权限执行action mapping都有几个单独的方法。这给我们提供了极大的弹性空间。Struts的RequestProcessor对每个请求处理步骤都提供了默认的实 现方法。这意味着,你可以重写你感兴趣的方法,而其余剩下的保留默认实现。例如,Struts默认调用request.isUserInRole()检查 用户是否有权限执行当前的ActionMapping,但如果你需要从数据库中查找,那么你要做的就是重写processRoles()方法,并根据用户 角色返回true 或 false。
首先我们看一下process()方法的默认实现方式,然后我将解释RequestProcessor类里的每个默认的方法,以便你决定要修改请求处理的哪一部分。
1、processMultipart(): 在这个方法中,Struts读取request以找出contentType是否为 multipart/form-data。假如是,则解析并将其打包成一个实现HttpServletRequest的包。当你成生一个放置数据的 HTML FORM时,request的contentType默认是application/x-www-form-urlencoded。但是如果你的form 的input类型是FILE-type允许用户上载文件,那么你必须把form的contentType改为multipart/form-data。如 这样做,你永远不能通过HttpServletRequest的getParameter()来读取用户提交的form值;你必须以 InputStream的形式读取request,然后解析它得到值。
2、processPath(): 在这个方法中,Struts将读取request的URI以判断用来得到ActionMapping元素的路径。
3、processLocale(): 在这个方法中,Struts将得到当前request的Locale;Locale假如被配置,将作为 org.apache.struts.action.LOCALE属性的值被存入HttpSession。这个方法的附作用是HttpSession会被 创建。假如你不想此事发生,可将在struts-config.xml 文件里ControllerConfig的local属性设置为false,如下:
<controller>
<set-property property="locale" value="false"/>
</controller>
4、processContent():通过调用response.setContentType()设置response的contentType。这个方法首先会试着的得到配置在struts-config.xml里的contentType。默认为text/html,重写方法如下:<set-property property="locale" value="false"/>
</controller>
<controller>
<set-property property="contentType" value="text/plain"/>
</controller>
5、processNoCache():Struts将为每个response的设置以下三个header,假如已在struts 的config.xml将配置为no-cache。<set-property property="contentType" value="text/plain"/>
</controller>
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 1);
假如你想设置为no-cache header,在struts-config.xml中加如以下几行response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 1);
<controller>
<set-property property="noCache" value="true"/>
</controller>
6、processPreprocess():这是一个一般意义的预处理hook,其可被子类重写。在RequestProcessor里的实现什么都没有做,总是返回true。如此方法返回false会中断请求处理。<set-property property="noCache" value="true"/>
</controller>
7、processMapping():这个方法会利用path信息找到ActionMapping对象。ActionMapping对象在struts-config.xml file文件里表示为<action>
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
8、processRoles(): Struts的web 应用安全提供了一个认证机制。这就是说,一旦用户登录到容器,Struts的processRoles()方法通过调用request.isUserInRole()可以检查他是否有权限执行给定的ActionMapping。
<action path="/addUser" roles="administrator"/>
假如你有一个AddUserAction,限制只有administrator权限的用户才能新添加用户。你所要做的就是在AddUserAction 的action元素里添加一个值为administrator的role属性。9、processActionForm():每个ActionMapping都有一个与它关联的ActionForm类。struts在处理ActionMapping时,他会从<action>里name属性找到相关的ActionForm类的值。
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
10、processPopulate()::在这个方法里,Struts将匹配的request parameters值填入ActionForm类的实例变量中。
11、processValidate():Struts将调用ActionForm的validate()方法。假如validate()返回ActionErrors,Struts将用户转到由<action>里的input属性标示的页面。
12、processForward() and processInclude():在这两个方法里,Struts检查<action>元素的forward和include属性的值,假如有配置,则把forward和include 请求放在配置的页面内。
<action forward="/Login.jsp" path="/loginInput"/>
<action include="/Login.jsp" path="/loginInput"/>
你 可以从他们的名字看出其不同之处。processForward()调用 RequestDispatcher.forward(),,processInclude()调用 RequestDispatcher.include()。假如你同时配置了orward 和include 属性,Struts总会调用forward,因为forward,是首先被处理的。<action include="/Login.jsp" path="/loginInput"/>
13、processActionCreate():这个方法从<action>的type属性得到Action类名,并创建返回它的实例。在这里例子中struts将创建一个com.sample.NewContactAction类的实例。
14、processActionPerform():这个方法调用Action 类的execute()方法,其中有你写入的业务逻辑。
15、processForwardConfig():Action类的execute()将会返回一个ActionForward类型的对象,指出哪一页面将展示给用户。因此Struts将为这个页面创建RequestDispatchet,然后再调用RequestDispatcher.forward()方法。
以 上列出的方法解释了RequestProcessor在请求处理的每步默认实现及各个步骤执行的顺序。正如你所见,RequestProcessor很有 弹性,它允许你通过设置<controller>里的属性来配置它。例如,假如你的应用将生成XML内容而不是HTML,你可以通过设置 controller的某个属性来通知Struts。