创建你自己的RequestProcessor
通过上面,我们了解到了RequestProcessor的默认实现是如何工作的。现在我们要演示一个例子来说明如何定制你自己的RequestProcessor。为了展示创建用户定制的RequestProcessor,我们将会让我们的示例实现下面两个业务需求:
·我们想创建一个ContactImageAction类,它将生成图片而不是平常的HTML页面。
·在每个请求处理之前,我们都想通过检查session中的userName属性来确定用户是否已经登陆。如果那个属性没有找到,我们会把用户重定向到登陆页面。
我们将分两步实现这些业务需求。
1、创建你的CustomRequestProcessor类,它将继承自RequestProcessor类,如下:
public class CustomRequestProcessor extends RequestProcessor { protected boolean processPreprocess ( HttpServletRequest request,HttpServletResponse response) { HttpSession session = request.getSession(false); //If user is trying to access login page // then don't check if( request.getServletPath().equals("/loginInput.do") || request.getServletPath().equals("/login.do") ) return true; //Check if userName attribute is there is session. //If so, it means user has allready logged in if( session != null && session.getAttribute("userName") != null) return true; else{ try{ //If no redirect user to login Page request.getRequestDispatcher("/Login.jsp").forward(request,response); }catch(Exception ex){ } } return false; }
protected void processContent(HttpServletRequest request, HttpServletResponse response) { //Check if user is requesting ContactImageAction // if yes then set image/gif as content type if( request.getServletPath().equals("/contactimage.do")){ response.setContentType("image/gif"); return; } super.processContent(request, response); } } |
在CustomRequestProcessor类的processPreprocess方法中,我们检查session的userName属性,如果没有找到,就将用户重定向到登陆页面。
对于生成图片作为输出的需求,我们必须覆盖processContent方法,首先检查请求是否是/contactimage路径。如果是的话,我们就会将contentType设置为image/gif;否则设置为text/html。
2、在你的struts-config.xml文件的<action-mappint>元素之后加入下面的文字,告诉Struts CustomRequestProcessor应当被用作RequestProcessor类:
<controller> <set-property property="processorClass"value="com.sample.util.CustomRequestProcessor"/> </controller> |
请注意,当你只有很少的action类需要生成非text/html类型的输出时,你覆写processContent()方法是OK的。如果不是这样子的话,你应该创建一个Struts的子应用来处理请求生成图片的Action,并为它们将contentType设置为image/gif。
Struts的Tiles框架就是使用它自己的RequestProcessor来装饰Struts的输出。
ActionServlet
如果你查看你的Struts web应用的web.xml,你会看到这样的文字:
<web-app > <servlet> <servlet-name>action=</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <!-- All your init-params go here--> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app > |
这意味着ActionServlet负责处理你所有Struts的请求。你可以创建一个ActionServlet的子类,当应用启动,关闭,每个请求的时候做一些特定的事情。但是在继承ActionServlet类之前,你应该尽量创建一个PlugIn或RequestProcessor去解决你的问题。在Servlet1.1之前,Tiles框架是基于ActionServlet来修饰生成的响应。但是从1.1之后,它开始使用TilesRequestProcessor类。
总结 决定开发你自己的MVC框架是一个非常大的决定,你必须要考虑开发和维护框架代码所花费的时间和资源。Struts是一个非常强大和稳定的框架,你可以修改它来满足你绝大多数的业务需求。
但另一方面,也不要草率地做出扩展Struts的决定。如果你在RequestProcessor中写了一些性能比较低的代码,它将会在每次请求时执行,因而降低你整个应用的效率。而且还是有一些情况,开发自己的MVC框架要比扩展Struts好。