自定义mvc(一、二)
1. 什么是MVC
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,
它是一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码
Model1 jsp+jdbc
Model2 ->MVC
2. 自定义MVC工作原理图
工具类:
ActionModel.java
ConfigModel.java
ConfigModelFactory.java
ForwardModel.java
mvc.xml
3. 通过XML对自定义mvc框架进行增强
3.1将子控制器信息动态配置到mvc.xml中
DispatcherServlet.java
package com.huang.framework; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.beanutils.BeanUtils; /** * 中央控制器 * 作用:接收请求,通过请求寻找处理请求的对应的自控器 * @author Admin * */ public class DispatcherServlet extends HttpServlet { private static final long serialVersionUID = 7565258196310251777L; // private Map<String, Action> actionMap=new HashMap<>(); // 在configModel对象中包含了所有的子控制器 private ConfigModel configModel; public void init() { // actionMap.put("/addCal", new AddCalAction()); // actionMap.put("/delCal", new DelCalAction()); // actionMap.put("/cheCal", new CheCalAction()); // actionMap.put("/chuCal", new ChuCalAction()); try { configModel=ConfigModelFactory.newInstance(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { init(); String url=req.getRequestURI(); url=url.substring(url.lastIndexOf("/"), url.lastIndexOf(".")); // Action action=actionMap.get(url); ActionModel actionModel=configModel.get(url); if(actionModel==null) { throw new RuntimeException("你没有配置action标签,找不到对应的子控制器来处理浏览器发送的请求!!"); } try { Action action= (Action) Class.forName(actionModel.getType()).newInstance(); if(action instanceof ModelDrivern) { ModelDrivern mdDrivern = (ModelDrivern) action; // 此时的model的所有属性值是null的 Object model=mdDrivern.getModel(); BeanUtils.populate(model, req.getParameterMap()); // 我们可以req.getParameterMap()的值通过反射的方式将其塞进model实例 // Map<String, String[]> parameterMap=req.getParameterMap(); // Set<Entry<String, String[]>> entrySet=parameterMap.entrySet(); // Class<? extends Object> clz= model.getClass(); // for (Entry<String, String[]> entry : entrySet) { // Field field=clz.getField(entry.getKey()); // field.setAccessible(true); // field.set(model, entry.getValue()); // // } } String code=action.execute(req, resp); ForwardModel forwardModel= actionModel.get(code); if(forwardModel!=null) { String jspPath=forwardModel.getPath(); if("false".equals(forwardModel.getRedirect())) { //做转发的处理 req.getRequestDispatcher(jspPath).forward(req, resp); } else { resp.sendRedirect(req.getContextPath()+"/"+jspPath); } } } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
3.2针对mvc框架的结果码进行处理
cal.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> <script type="text/javascript"> function huang(num){ if(num==1){ calForm.action="${pageContext.request.contextPath }/Cal.action?methodName=add"; } else if(num==2){ calForm.action="${pageContext.request.contextPath }/Cal.action?methodName=del"; } else if(num==3){ calForm.action="${pageContext.request.contextPath }/Cal.action?methodName=che"; } else if(num==4){ calForm.action="${pageContext.request.contextPath }/Cal.action?methodName=chu"; } calForm.submit(); } </script> </head> <body> <form name="calForm" action="" method="post"> 第一个数:<input type="text" name="num1"><br> 第二个数:<input type="text" name="num2"><br> <button onclick="huang(1)">+</button> <button onclick="huang(2)">-</button> <button onclick="huang(3)">*</button> <button onclick="huang(4)">/</button> </form> </body> </html>
3.3将一组操作放到一个子控制器中
ActionSupport.java
package com.huang.framework; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 增强版的子控制器 * 原来的子控制器只能一个用户请求 * 有时候,用户请求是多个,但是都是操作同一张表,那么原有的子控制器代码编写繁琐 * 增强版的作用 * 将一组相关的操作放到一个Action中 * @author Admin * */ public class ActionSupport implements Action { @Override public String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // add/del/che/chu String methodName=req.getParameter("methodName"); String code=null; // class CalAction extends ActionSupport // this在这里指的是CalAction它的一个类实例 try { Method m=this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class); m.setAccessible(true); code=(String) m.invoke(this, req,resp); } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } return code; } }
3.4利用模型驱动接口对mvc框架进行增强
CalAction.java
package com.huang.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.huang.entity.Cal;
import com.huang.framework.ActionSupport;
import com.huang.framework.ModelDrivern;
public class CalAction extends ActionSupport implements ModelDrivern<Cal>{
private Cal cal=new Cal();
public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// String num1=req.getParameter("num1");
// String num2=req.getParameter("num2");
// Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
req.setAttribute("res", cal.getNum1() + cal.getNum2());
// req.getRequestDispatcher("res.jsp").forward(req, resp);
return "res";
}
public String del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// String num1=req.getParameter("num1");
// String num2=req.getParameter("num2");
// Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
req.setAttribute("res", cal.getNum1() - cal.getNum2());
// req.getRequestDispatcher("res.jsp").forward(req, resp);
return "res";
}
public String che(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// String num1=req.getParameter("num1");
// String num2=req.getParameter("num2");
// Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
req.setAttribute("res", cal.getNum1() * cal.getNum2());
// req.getRequestDispatcher("res.jsp").forward(req, resp);
return "res";
}
public String chu(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// String num1=req.getParameter("num1");
// String num2=req.getParameter("num2");
// Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
req.setAttribute("res", cal.getNum1() / cal.getNum2());
// req.getRequestDispatcher("res.jsp").forward(req, resp);
return "res";
}
@Override
public Cal getModel() {
return cal;
}
}
3.5解决框架配置文件的冲突问题
web.xml
<?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"> <display-name>T226_mvc</display-name> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>com.huang.framework.DispatcherServlet</servlet-class> <init-param> <param-name>xmlPath</param-name> <param-value>/mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app>