【SSH进阶之路】一步步重构MVC实现Struts框架——从一个简单MVC开始(三)

【SSH进阶之路】Struts基本原理 + 实现简单登录(二),我们介绍MVC和Struts的基本理论,并实现了一个简单登录的实例。从中我们知道了,Struts是MVC的框架,MVC其实是Model2,M代表了模型,我们可以理解为业务逻辑,V代表了视图,主要是界面显示,使用jsp显示,C代表控制,控制最典型方式是使用servlet,可以获取参数,调用业务逻辑,另外还可以转向其他界面。

      经过对上篇博客的介绍,我们知道了Struts对MVC做了封装,Struts到底是怎么封装的MVC,一直还没有解决,从这篇博客开始,我们一步步重构MVC实现一个基本的Struts框架的雏形,帮助我们更深入的学习Struts的基本流程提供保证。下面我们开始。

      我们严格按照上篇博客Model2的时序图或如下图,使用jsp+servlet来给大家演示一个简单的MVC,一步步的重构,完善,把框架的一个实现给大家引出来。 

 

     

 

假设是一个关于用户的增、删、改、查的功能,下面我们敲一下各部分的代码。新建java web项目,test_struts1,如下图:

       


首先,新建一个索引页面,提供一个表单,仅仅提供一个用户姓名,比如实现添加用户功能,作为主界面。


index.jsp

[java] view plain copy
 print?
  1. <%@ page language="java" contentType="text/html; charset=GB18030"  
  2.     pageEncoding="GB18030"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <html>  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=GB18030">  
  7. <title>Insert title here</title>  
  8. </head>  
  9. <body>  
  10.     <form action="servlet/addUser.do" method="post">  
  11.         姓名:<input type="text" name="username"><br>  
  12.         <input type="submit" value="提交"><br>  
  13.     </form>  
  14. </body>  
  15. </html>  

C,控制器,使用Servlet来实现控制器的职责,取得表单数据,调用业务逻辑,转向页面。客户端一点提交,提交到Servlet,代码如下:

TestServlet.java

[java] view plain copy
 print?
  1. package com.liang.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.  * 使用servlet做相关的控制,转向多个(V)视图 
  12.  * @author liang 
  13.  * 
  14.  */  
  15. public class TestServlet extends HttpServlet {  
  16.   
  17.     @Override  
  18.     protected void doGet(HttpServletRequest request, HttpServletResponse response)  
  19.             throws ServletException, IOException {  
  20.         //取得访问的URI  
  21.         String reqeuestURI = request.getRequestURI();  
  22.         System.out.println(reqeuestURI);  
  23.         //截取URI,获得路径  
  24.         String path = reqeuestURI.substring(reqeuestURI.indexOf("/",1), reqeuestURI.indexOf("."));  
  25.         System.out.println(path);  
  26.         //获得表单数据  
  27.         String username = request.getParameter("username");  
  28.           
  29.         UserManager userManager = new UserManager();  
  30.           
  31.         String forward ="";  
  32.         //根据url执行相关的功能  
  33.         //等于添加,调用添加方法,添加成功转到添加页面  
  34.         if("/servlet/addUser".equals(path)){  
  35.             //调用添加的业务逻辑  
  36.             userManager.add(username);  
  37.             forward ="/add_success.jsp";  
  38.             //删除,调用删除方法,删除成功转到删除  
  39.         }else if("/servlet/delUser".equals(path)){  
  40.             //调用删除的业务逻辑  
  41.             userManager.del(username);  
  42.             forward ="/del_success.jsp";  
  43.         //修改,调用修改方法,修改成功转到修改页面  
  44.         }else if("/servlet/modifyUser".equals(path)){  
  45.             //调用修改的业务逻辑  
  46.             userManager.modify(username);  
  47.             forward ="/modify_success.jsp";  
  48.         //查询,调用查询方法,查询成功转到查询成功页面  
  49.         }else if("/servlet/queryUser".equals(path)){  
  50.             //调用查询的业务逻辑  
  51.             List userList = userManager.query(username);  
  52.             request.setAttribute("userList", userList);  
  53.             forward ="/query_success.jsp";  
  54.         }else{  
  55.             throw new RuntimeException("请求失败");  
  56.         }  
  57.         //统一完成转向  
  58.         request.getRequestDispatcher(forward).forward(request, response);  
  59.     }  
  60.   
  61.     @Override  
  62.     protected void doPost(HttpServletRequest request, HttpServletResponse response)  
  63.             throws ServletException, IOException {  
  64.         doGet(request,response);  
  65.     }  
  66.   
  67. }  

     控制器需要调用业务逻辑和转到相应页面,给用户提示一下,成功或失败,代码如下:


M,业务逻辑,我们完成增、删、改、查的功能,不再操作数据库,以控制台打印信息的形式,做简单的演示。

UserManager.java

[java] view plain copy
 print?
  1. package com.liang.servlet;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. public class UserManager {  
  7.   
  8.     //添加用户  
  9.     public void add(String username){  
  10.           
  11.         System.out.println("UserManager.add()-->>>username:" + username);  
  12.     }  
  13.     //删除用户  
  14.     public void del(String username){  
  15.           
  16.         System.out.println("UserManager.del()-->>>username:" + username);  
  17.     }  
  18.     //修改用户  
  19.     public void modify(String username){  
  20.       
  21.     System.out.println("UserManager.modify()-->>>username:" + username);  
  22.     }  
  23.     //查询用户  
  24.     public List query(String username){  
  25.           
  26.         System.out.println("UserManager.query()-->>>username:" + username);  
  27.         List userList = new ArrayList();  
  28.         userList.add("a");  
  29.         userList.add("b");  
  30.         userList.add("c");  
  31.         userList.add("d");  
  32.         return userList;  
  33.           
  34.     }  
  35. }  

转向页面,添加成功jsp:

add_success.jsp

[java] view plain copy
 print?
  1. <%@ page language="java" contentType="text/html; charset=GB18030"  
  2.     pageEncoding="GB18030"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <html>  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=GB18030">  
  7. <title>Insert title here</title>  
  8. </head>  
  9. <body>  
  10.     添加成功!  
  11. </body>  
  12. </html>  

删除成功页面和修改成功页面同上,只有一句表示不同页面。

查询成功页面,query_success.jsp

 

[java] view plain copy
 print?
  1. <%@ page language="java" contentType="text/html; charset=GB18030"  
  2.     pageEncoding="GB18030"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <html>  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=GB18030">  
  7. <title>Insert title here</title>  
  8. </head>  
  9. <body>  
  10.     查询成功!  
  11.     <p></p>  
  12.     <%=request.getAttribute("userList") %>  
  13. </body>  
  14. </html>  

配置信息web.xml

[java] view plain copy
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5"   
  3.     xmlns="http://java.sun.com/xml/ns/javaee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  6.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  7.   <welcome-file-list>  
  8.     <welcome-file>index.jsp</welcome-file>  
  9.   </welcome-file-list>  
  10.   <!-- 配置TestServlet类 -->  
  11.   <servlet>  
  12.     <servlet-name>TestServlet</servlet-name>  
  13.     <servlet-class>com.liang.servlet.TestServlet</servlet-class>  
  14.   </servlet>  
  15.   <!-- 怎么访问,与jsp的action的路径一致 -->  
  16.   <servlet-mapping>  
  17.     <servlet-name>TestServlet</servlet-name>  
  18.     <!-- 只要是.do请求都会到达servlet -->  
  19.     <url-pattern>*.do</url-pattern>  
  20.   </servlet-mapping>  
  21.     
  22. </web-app>  


最后,搭建tomacat,部署访问。控制台的打印信息,成功的跳转页面不再展示,效果如下:




如果你想访问业务逻辑其他功能,只需要修改index.jsp中的action的值即可。到此为止,我们实现了一个简单的用于增删改查用户功能的MVC。


我们现在看一下上面TestServlet的代码,有很多的问题:

1、所有的业务逻辑和跳转路径都耦合在TestServlet这个类里面了。想添加其他需求,需要修改TestServlet,违反了开放封闭原则。

2、在Servlet里面存在很多的if-else语句,if语句很不稳定,总需要改变。

     假如要再添加一个查询功能,需要修改servlet,添加一个if..else语句,太麻烦了,违反了开放封闭原则,扩展性一点都不好。

3、所有的转向页面都写死了,显示和控制分离,如果想换一个视图,要修改代码。



     我们一步步将上面的问题都解决,最后实现Struts框架的雏形。下篇博客【SSH进阶之路】一步步重构MVC实现Struts框架——封装业务逻辑和跳转路径(四),首先解决我们的第一个问题。


     源码下载


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章