自定义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>

 

posted @ 2019-06-25 18:12  宇大..大  阅读(129)  评论(0编辑  收藏  举报