Servlet是如何实现MVC的

来源:互联网 发布:美丽芭蕾是什么软件 编辑:程序博客网 时间:2024/05/07 02:39

转:http://blog.csdn.net/laner0515/article/details/11266673

 


Servlet是一种服务器端的编程语言,是J2EE中比较关键的组成部分,Servlet技术的推出,扩展了Java语言在服务器端开发的功能,巩固了Java语言在服务器端开发中的地位,而且现在使用非常广泛的JSP技术也是基于Servlet的原理.

JSP+JavaBeans+Servlet成为实现MVC模式的一种有效的选择。


如果我们要实现一个对用户的增删改查,并且要求符合对扩展开发,对修改关闭的原则,该怎么做呢?

首先,这是我们的类图以及类与类之间调用的时序图。




根据UML图来实现代码:

TestServlet类

[html] view plain copy print?
  1. package com.bjpowernode.servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.List;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. public class TestServlet extends HttpServlet {  
  12.   
  13.       
  14.     protected void doGet(HttpServletRequest request, HttpServletResponse response)  
  15.             throws ServletException, IOException {  
  16.         String requestURI = request.getRequestURI();  
  17.         System.out.println("requestURI=" + requestURI);  
  18.         String path = requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf("."));  
  19.         System.out.println("path = " +path);  
  20.           
  21.         String username = request.getParameter("username");  
  22.           
  23.         Action action = null;  
  24.         if("/servlet/delUser".equals(path)){  
  25.             action = new DelUserAction();  
  26.         }else if("/servlet/addUser".equals(path)){  
  27.             action = new AddUserAction();  
  28.         }else if("/servlet/modifyUser".equals(path)){  
  29.             action = new ModifyAction();  
  30.         }else if("/servlet/queryUser".equals(path)){  
  31.             action = new QueryUserAction();  
  32.         }else{  
  33.             throw new RuntimeException("请求失败");  
  34.         }  
  35.         String forward ="";  
  36.         try {  
  37.             forwardaction.execute(request, response);  
  38.         } catch (Exception e) {  
  39.             e.printStackTrace();  
  40.         }  
  41.         request.getRequestDispatcher(forward).forward(request, response);  
  42.           
  43.   
  44.     }  
  45.   
  46.   
  47.     protected void doPost(HttpServletRequest request, HttpServletResponse response)  
  48.             throws ServletException, IOException {  
  49.         doGet(request,response);  
  50.     }  
  51.   
  52. }  

抽象接口Action

[html] view plain copy print?
  1. package com.bjpowernode.servlet;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.http.HttpServletResponse;  
  5.   
  6. public interface Action {  
  7.   
  8.     public String execute(HttpServletRequest request, HttpServletResponse response)  
  9.     throws Exception;  
  10.       
  11. }  


添加类,这里就只写添加类了,其他类一样

[html] view plain copy print?
  1. package com.bjpowernode.servlet;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.http.HttpServletResponse;  
  5.   
  6. public class AddUserAction implements Action {  
  7.   
  8.     public String execute(HttpServletRequest request,  
  9.             HttpServletResponse response) throws Exception {  
  10.         String username = request.getParameter("username");  
  11.         //int age = Integer.parseInt(request.getParameter("username"));  
  12.         //String sex = request.getParameter("sex");  
  13.           
  14.         //调用业务逻辑  
  15.         UserManager userManager = new UserManager();  
  16.         userManager.add(username);  
  17.           
  18.         return "/add_success.jsp";  
  19.     }  
  20.   
  21. }  

Web.xml配置

[html] view plain copy print?
  1. <welcome-file-list>  
  2.     <welcome-file>index.jsp</welcome-file>  
  3.   </welcome-file-list>  
  4.     
  5.   <servlet>  
  6.     <servlet-name>TestServlet</servlet-name>  
  7.     <servlet-class>com.bjpowernode.servlet.TestServlet</servlet-class>  
  8.   </servlet>  
  9.   <servlet-mapping>  
  10.      <servlet-name>TestServlet</servlet-name>  
  11.      <!--  
  12.      <url-pattern>/servlet/TestServlet</url-pattern> 
  13.       -->  
  14.       <url-pattern>*.do</url-pattern>  
  15.   </servlet-mapping>  

 

这里我们发现,在testAction类中,用到了大量的if和else,而当我们需要扩展一个上传类的时候,就需要修改if/else,所以,这就不符合对扩展开发,对修改关闭原则,所以,我们需要把这部分提取出来,配置到配置文件里,用反射进行配置。

 

我们需要先配置配置文件

[html] view plain copy print?
  1. <action-config>  
  2.         <action path ="/servlet/delUser" type = "com.bjpowernode.servlet.DelUserAction">  
  3.             <forward name = "success">del_success.jsp</forward>  
  4.             <forward name = "error">del_error.jsp</forward>  
  5.         </action>   
  6.         <action path ="/servlet/addUser" type = "com.bjpowernode.servlet.AddUserAction">  
  7.             <forward name = "success">add_success.jsp</forward>  
  8.             <forward name = "error">add_error.jsp</forward>  
  9.         </action>   
  10.         <action path ="/servlet/modifyUser" type = "com.bjpowernode.servlet.ModifyAction">  
  11.             <forward name = "success">modify_success.jsp</forward>  
  12.             <forward name = "error">modify_error.jsp</forward>  
  13.         </action>   
  14.         <action path ="/servlet/queryUser" type = "com.bjpowernode.servlet.QueryUserAction">  
  15.             <forward name = "success">query_success.jsp</forward>  
  16.             <forward name = "error">query_error.jsp</forward>  
  17.         </action>   
  18.   </action-config>  

需要获取actionMapping对象

[html] view plain copy print?
  1. ActionMapping{  
  2.     private String path;  
  3.     private String type;  
  4.    Map forwardMap;  
  5.     
  6.     
  7.   }  
  8.   forwardMap{  
  9.     key = "success";  
  10.     value ="/del_success.jsp"  
  11.     key ="error"  
  12.     value ="del_error.jsp";  
  13.    
  14.    
  15.    
  16.   }  
  17.    
  18.   Map map = new HashMap();  
  19.   map.put("/servlet/delUser",actionMapping);  
  20.   map.put("/servlet/addUser",actionMapping);  
  21.   map.put("/servlet/modifyUser",actionMapping);  
  22.   map.put("/servlet/queryUser",actionMapping);  
  23.    
  24.  // 如果是删除ActionMapping存储如下:  
  25.   actionMapping{  
  26.     path ="/servlet/delUser";  
  27.    type ="com.bjpowernode.servlet.DelUserAction"  
  28.     forwardMap{  
  29.         key ="success",value ="/del_success.jsp"  
  30.         key ="error",value"/del_error.jsp"  
  31.     }  
  32.   }  
  33.    

最后根据获取的对象采用反射来动态实例化Action,达到我们的目的。

[html] view plain copy print?
  1.  String path = "/servlet/delUser";  
  2.   
  3. /  根据截取的URL请求,到Map中取得本次请求对应的Action  
  4.     ActionMapping actionMapping =(ActionMapping)map.get(path);  
  5.       
  6. /取得本次请求对应的Action类的完整路径  
  7.  String type = actionMapping.getType();  //com.bjpowernode.servlet.DelUserAction  
  8.   
  9. // 采用反射动态实例化Action  
  10.  Action action  = (Action)class.forName(type).newInstance();  
  11.   
  12. /动态待用Action中的execute方法  
  13.  String forward = action.execute(request.response);  
  14.   
  15.  //根据路径完成转向        
  16. request.getRequestDispatcher(forward).forward(request, response);  

 

        这样,我们基本就是实现了对扩展开发,对修改封闭的原则,但是,这仅仅是一个功能我们就需要做这么多事情,写这么多代码,对程序员来说这是一项不小的工作量,那么我们有没有其他的办法让我们的工作量小一点呢?


0 0
原创粉丝点击