MVC演化、理解

来源:互联网 发布:二维数组元素的排序 c 编辑:程序博客网 时间:2024/06/04 18:54

我们先不解释什么叫MVC,针对项目中的问题,解决推进慢慢把项目改进发展成MVC来理解它。

无论是jsp中嵌入java代码,或者servlet内嵌html都会使代码混乱,不便分工合作和后期开发。我们现在让jsp只负责显示,而代码控制给servlet负责,就是处理请求交给servlet,这样我们就把项目的显示和控制分离开来。

以用户注册作为例子,首先要有页面register.jsp输入用户信息,因为jsp只负责显示,所以前面要有一个servlet(register.do)控制跳转到register.jsp页面,然后视图提交给另一个servlet(user_add.do)进行用户添加,再跳转到用户列表(user_list.jsp)页面,同样要用servlet(user_list.do)控制。(如果没有user_list.do,让user_add.do把user_list.do做的事给做了,除了职责不单一,还会有重复提交的隐患另作处理,如果不用服务器端跳转用客户端跳转,如果把jsp文件放在WEB-INF是找不到的),即

register.do--------forword()------>register.jsp------------submit()-------->user_add.do-------------redirect()------>user_list.do---------forword()------>user_list.jsp

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">    <servlet>    <servlet-name>UserRegister</servlet-name>    <servlet-class>com.yan.mvc.servlet.UserRegister</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>UserRegister</servlet-name>    <url-pattern>/register.do</url-pattern>  </servlet-mapping>    <servlet>    <servlet-name>UserAdd</servlet-name>    <servlet-class>com.yan.mvc.servlet.UserAdd</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>UserAdd</servlet-name>    <url-pattern>/user_add.do</url-pattern>  </servlet-mapping>     <servlet>    <servlet-name>UserList</servlet-name>    <servlet-class>com.yan.mvc.servlet.UserList</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>UserList</servlet-name>    <url-pattern>/user_list.do</url-pattern>  </servlet-mapping></web-app>

register.do

package com.yan.mvc.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class UserRegister extends HttpServlet {private static final long serialVersionUID = 1L;              public UserRegister() {        super();           }protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.getRequestDispatcher("/WEB-INF/user/register.jsp").forward(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}
register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><form action="user_add.do" method="post"><table align="center" width="500" border="1"><tr><td>用户名称:</td><td><input type="text" name="name" value=""/></td></tr><tr><td>用户年龄:</td><td><input type="text" name="age" value=""/></td></tr><tr><td colspan="2"><input type="submit" value="添加用户"></td></tr></table></form></body></html>                                                                                                        
user_add.do
package com.yan.mvc.servlet;import java.io.IOException;import java.util.ArrayList;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.yan.mvc.model.User;public class UserAdd extends HttpServlet {public UserAdd() {super();}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("UTF-8");String name=req.getParameter("name");int age=Integer.parseInt(req.getParameter("age"));List<User> users=(List<User>)req.getSession().getServletContext().getAttribute("storeUsers");if(users==null){users=new ArrayList<User>();}User u=new User(name,age);users.add(u);req.getSession().getServletContext().setAttribute("storeUsers", users);resp.sendRedirect("user_list.do");}}

user_list.do

package com.yan.mvc.servlet;import java.io.IOException;import java.util.List;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.yan.mvc.model.User;public class UserList extends HttpServlet {private static final long serialVersionUID = 1L;           /**     * @see HttpServlet#HttpServlet()     */    public UserList() {        super();        // TODO Auto-generated constructor stub    }/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {List<User>users=(List<User>)request.getSession().getServletContext().getAttribute("storeUsers");request.setAttribute("users", users);request.getRequestDispatcher("/WEB-INF/user/user_list.jsp").forward(request, response);}}
user_list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title><style type="text/css">table{border-bottom:1px solid #000;border-right:1px solid #000;}table td{border-top:1px solid #000;border-left:1px solid #000;padding:5px;}</style></head><body><a href="register.do" >添加用户</a><table align="center" width="200" cellspacing="0"  cellpadding="0"><tr><td>用户名</td><td>年龄</td></tr><c:if test="${empty users }"><tr><td colspan="2">没有用户信息</td></tr></c:if><c:if test="${not empty users}"><c:forEach var="user" items="${users}"><tr><td>${user.name}</td><td><c:choose> <c:when test="${user.age gt 17 }">${user.age }</c:when><c:otherwise>未成年</c:otherwise></c:choose></td></tr></c:forEach></c:if></table></body>

----------------------------------------------------------------------------------------------------
可以发现这样虽然实现目的,将控制与视图显示分离开来,但明显一个jsp就有一个servlet,太多了,我们可以将它们进行合并成一个,可以使用传参的方式

user.do

package com.yan.mvc.servlet;import java.io.IOException;import java.util.ArrayList;import java.util.List;import javax.servlet.annotation.WebServlet;import javax.jws.WebService;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.yan.mvc.model.User;@WebServlet("/user.do")public class UserServlet extends HttpServlet {private static final long serialVersionUID = 1L;           /**     * @see HttpServlet#HttpServlet()     */    public UserServlet() {        super();        // TODO Auto-generated constructor stub    }/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request,response);}/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTF-8");//动态获取访问的是哪个操作                String method=request.getParameter("method");if("add".equals(method)){add(request,response);}else if("list".equals(method)){list(request,response);}else if("register".equals(method)){register(request,response);}}protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String name=req.getParameter("name");int age=Integer.parseInt(req.getParameter("age"));List<User> users=(List<User>)req.getSession().getServletContext().getAttribute("storeUsers");if(users==null){users=new ArrayList<User>();}User u=new User(name,age);users.add(u);req.getSession().getServletContext().setAttribute("storeUsers", users);resp.sendRedirect("user.do?method=list");}protected void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {List<User>users=(List<User>)request.getSession().getServletContext().getAttribute("storeUsers");request.setAttribute("users", users);request.getRequestDispatcher("/WEB-INF/user/user_list.jsp").forward(request, response);}protected void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.getRequestDispatcher("/WEB-INF/user/register.jsp").forward(request, response);}}

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><form action="user.do?method=add" method="post"><table align="center" width="500" border="1"><tr><td>用户名称:</td><td><input type="text" name="name" value=""/></td></tr><tr><td>用户年龄:</td><td><input type="text" name="age" value=""/></td></tr><tr><td colspan="2"><input type="submit" value="添加用户"></td></tr></table></form></body></html>

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title><style type="text/css">table{border-bottom:1px solid #000;border-right:1px solid #000;}table td{border-top:1px solid #000;border-left:1px solid #000;padding:5px;}</style></head><body><a href="user.do?method=register" >添加用户</a><table align="center" width="200" cellspacing="0"  cellpadding="0"><tr><td>用户名</td><td>年龄</td></tr><c:if test="${empty users }"><tr><td colspan="2">没有用户信息</td></tr></c:if><c:if test="${not empty users}"><c:forEach var="user" items="${users}"><tr><td>${user.name}</td><td><c:choose> <c:when test="${user.age gt 17 }">${user.age }</c:when><c:otherwise>未成年</c:otherwise></c:choose></td></tr></c:forEach></c:if></table></body>

----------------------------------------------------------------------------------------------------
上面还有不足的地方,那就是如果操作很多,要写过多的if-else语句,怎么修改?第一时间想到了反射,根据参数自动选择要执行的方法

package com.yan.mvc.servlet;import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.yan.mvc.model.User;@WebServlet("/user.do")public class UserServlet extends HttpServlet {private static final long serialVersionUID = 1L;           /**     * @see HttpServlet#HttpServlet()     */    public UserServlet() {        super();        // TODO Auto-generated constructor stub    }/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request,response);}/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTF-8");String method=request.getParameter("method");try {Method m=this.getClass().getMethod(method,HttpServletRequest.class,HttpServletResponse.class);m.invoke(this, request,response);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}@SuppressWarnings("unchecked")public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String name=req.getParameter("name");int age=Integer.parseInt(req.getParameter("age"));List<User> users=(List<User>)req.getSession().getServletContext().getAttribute("storeUsers");if(users==null){users=new ArrayList<User>();}User u=new User(name,age);users.add(u);req.getSession().getServletContext().setAttribute("storeUsers", users);resp.sendRedirect("user.do?method=list");}@SuppressWarnings("unchecked")public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {List<User>users=(List<User>)request.getSession().getServletContext().getAttribute("storeUsers");request.setAttribute("users", users);request.getRequestDispatcher("/WEB-INF/user/user_list.jsp").forward(request, response);}public void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.getRequestDispatcher("/WEB-INF/user/register.jsp").forward(request, response);}}

可以发现现在增加方法,不用再去修改doPost(),如果用的是if-else则要不断增加else if语句。(体验反射神奇之处,不用修改,根据参数去执行某个方法,死的东西活过来了)
其实反射的那部分代码是通用的,更好的改进方法是提取出来,创建一个BaseServlet,让UserServlet去继承它。


package com.yan.mvc.servlet;import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class BaseServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTF-8");String method=request.getParameter("method");try {Method m=this.getClass().getMethod(method,HttpServletRequest.class,HttpServletResponse.class);m.invoke(this, request,response);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}}

package com.yan.mvc.servlet;import java.io.IOException;import java.util.ArrayList;import java.util.List;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.yan.mvc.model.User;@WebServlet("/user.do")public class UserServlet extends BaseServlet {private static final long serialVersionUID = 1L;         @SuppressWarnings("unchecked")public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String name=req.getParameter("name");int age=Integer.parseInt(req.getParameter("age"));List<User> users=(List<User>)req.getSession().getServletContext().getAttribute("storeUsers");if(users==null){users=new ArrayList<User>();}User u=new User(name,age);users.add(u);req.getSession().getServletContext().setAttribute("storeUsers", users);resp.sendRedirect("user.do?method=list");}@SuppressWarnings("unchecked")public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {List<User>users=(List<User>)request.getSession().getServletContext().getAttribute("storeUsers");request.setAttribute("users", users);request.getRequestDispatcher("/WEB-INF/user/user_list.jsp").forward(request, response);}public void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.getRequestDispatcher("/WEB-INF/user/register.jsp").forward(request, response);}}

这样一来真正通用,不仅是UserServlet,以后有什么AddressServlet、MessageServlet等等都可以去继承它,在这些servlet中我们只顾写需要的业务方法就好了(就好像UserServlet只要写add()、list()、register()这些方法,神奇!!!),

进一步把页面跳转代码给提取出来

package com.yan.mvc.servlet;import java.io.IOException;import java.util.ArrayList;import java.util.List;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.yan.mvc.model.User;@WebServlet("/user.do")public class UserServlet extends BaseServlet {private static final long serialVersionUID = 1L;         @SuppressWarnings("unchecked")public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String name=req.getParameter("name");int age=Integer.parseInt(req.getParameter("age"));List<User> users=(List<User>)req.getSession().getServletContext().getAttribute("storeUsers");if(users==null){users=new ArrayList<User>();}User u=new User(name,age);users.add(u);req.getSession().getServletContext().setAttribute("storeUsers", users);return "redirect:user.do?method=list";//resp.sendRedirect("user.do?method=list");}@SuppressWarnings("unchecked")public String list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {List<User>users=(List<User>)request.getSession().getServletContext().getAttribute("storeUsers");request.setAttribute("users", users);return "user/user_list.jsp";//request.getRequestDispatcher("/WEB-INF/user/user_list.jsp").forward(request, response);}public String register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//request.getRequestDispatcher("/WEB-INF/user/register.jsp").forward(request, response);return "user/register.jsp";}}

package com.yan.mvc.servlet;import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class BaseServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTF-8");String method=request.getParameter("method");try {Method m=this.getClass().getMethod(method,HttpServletRequest.class,HttpServletResponse.class);//获取要跳转到的页面
                        String rel=(String)m.invoke(this, request,response);String redirStr="redirect:";
//判断客户端跳转还是服务器端跳转if(rel.startsWith(redirStr)){response.sendRedirect(rel.substring(redirStr.length()));}else{request.getRequestDispatcher("/WEB-INF/"+rel).forward(request, response);}} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}}


                                             
0 0
原创粉丝点击