mvc(2)

MVC框架工作原理图

在这里插入图片描述

1.什么是MVC?

MVC全名:Model View Controller,其中Model(模型层)、View(视图层)、Controller(控制层)
它是一种软件设计典范,用于业务逻辑处理、数据、界面显示分离,

常用模式:
model1:jsp+jdbc
model2:mvc

三层架构和MVC的区别?
三层架构是一个经典的分层思想,将开发模式分为三层,每个人专注自己擅长模块即可
MVC是一种设计模式,其目的是让html和业务逻辑分开

2.MVC结构?

V(视图层)--》 JSP

C(控制层)--》 Servlet/Action

M(模型层)--》 Dao、Entity
1)实体域模型(entity层)
2)过程域模型(dao层)

注:1)不能跨层调用;
2)只能由上往下进行调用;View -> Controller -> Model

3.自定义MVC工作原理图

    *.action           调度           截取*(请求路径名) 处理具体业务逻辑

JSP -----------> Servlet(中央控制器)--------------------->Action(子控制器)—>Model(Dao、DB)

通过XML对自定义MVC框架进行3步增强

一、反射增强第一步:

1)config.xml建模

具体的xml建模点这个链接

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE config[
	<!ELEMENT config (action*)>
	<!ELEMENT action (forward*)>
	<!ELEMENT forward EMPTY>
	<!ATTLIST action 
		path CDATA #REQUIRED
		type CDATA #REQUIRED
	>
	<!ATTLIST forward
		name CDATA #REQUIRED
		path CDATA #REQUIRED
		redirect (true|false) "false"
	>
]>
	<!--
		config标签:可以包含0~N个action标签
	-->
<config>
	<!--
		action标签:可以饱含0~N个forward标签
		path:/开头的字符串,并且值必须唯一 非空
		type:字符串,非空
	-->
	<!-- <action path="/regAction" type="test.RegAction">
		
			forward标签:没有子标签; 
			name:字符串,同一action标签下的forward标签name值不能相同 ;
			path:/开头的字符串
			redirect:只能是false|true,允许空,默认值为false
		
		<forward name="failed" path="/reg.jsp" redirect="false" />
		<forward name="success" path="/login.jsp" redirect="true" />
	</action>
	<action path="/loginAction" type="test.LoginAction">
		<forward name="failed" path="/login.jsp" redirect="false" />
		<forward name="success" path="/main.jsp" redirect="true" />
	</action> -->

	<action type="com.zhouzhuolin.mvc.action.AddAction" path="/addAction">
		<forward name="rs" path="/rs.jsp" redirect="false"/>
	</action>

	<action type="com.zhouzhuolin.mvc.action.CalAction" path="/calAction">
		<forward name="rs" path="/rs.jsp" redirect="false"/>
	</action>

</config>

2)获取Action配置信息
3)反射机制实例化Action子控制器
4)将请求委托给子控制器处理并返回结果码
5)根据返回结果码进行页面跳转
重定向/转发

package com.zhouzhuolin.mvc.framework;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zhouzhuolin.mvc.action.AddAction;
import com.zhouzhuolin.mvc.action.HelloAction;
import com.zhouzhuolin.mvc.util.ActionModel;
import com.zhouzhuolin.mvc.util.ConfigModel;
import com.zhouzhuolin.mvc.util.ConfigModelFactory;
import com.zhouzhuolin.mvc.util.ForwardModel;


/**
 * 核心控制器(根据不同的请求路径名调用action下的子控制器)
 * @author LinGod
 *
 */
public class ActionServlet extends HttpServlet {
	
	private Map<String, Action> map=null;
	
	private ConfigModel configModel;
	
	@Override
	public void init() throws ServletException {
		// TODO Auto-generated method stub
		super.init();
		
//		map=new HashMap<String, Action>();
//		map.put("/helloAction", new HelloAction());
//		map.put("/addAction", new AddAction());
		
		try {
			configModel = ConfigModelFactory.createConfigModel();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 8941367292695204397L;
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		this.doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//		获取请求路径
		String uri=req.getRequestURI();
		
//		截取请求路径名
		int start=uri.lastIndexOf("/");
		int end=uri.lastIndexOf(".");
		
//		获取请求路径名
		String actionName=uri.substring(start, end);
		
//		根据请求路径名获取action子控制器
//		Action action = map.get(actionName);
//		System.out.println(action.getClass().getName());
		ActionModel actionModel = configModel.get(actionName);
		if (actionModel == null) {
			throw new RuntimeException("没action中的path");
		}
		
		try {
			Action action = (Action) Class.forName(actionModel.getType()).newInstance();
			
//		将请求委托给action子控制器处理
			String coda=action.execute(req, resp);
			ForwardModel forwardModel = actionModel.get(coda);
			if (null==forwardModel) {
				throw new RuntimeException("forwardModel不存在");
			}
			if (forwardModel.isRedirect()) {
				resp.sendRedirect(req.getContextPath()+forwardModel.getPath());
			}else {
				req.getRequestDispatcher(forwardModel.getPath()).forward(req, resp);
			}
			
		} 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();
		}	
	}
}

二、反射增强第二步: 将一组相关的操作放到一个Action中(反射调用方法)

1)创建DispatcherAction类
DispatcherAction extends Action

2)根据请求参数获取方法名,利用反射机制调用方法
参数名:methodName:add/minus/mul/div

package com.zhouzhuolin.mvc.framework;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DispatcherAction extends Action {

	@Override
	public final String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
			String methodName=getReqMethodName(req);
			Class cla=this.getClass();
			Method method = cla.getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
			String code=(String) method.invoke(this, req,resp);
			return code;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	
	private String getReqMethodName(HttpServletRequest req) {
		String methodName = req.getParameter("methodName");
		
		Map<String, String[]> map = req.getParameterMap();
		Set<Entry<String, String[]>> entrySet = map.entrySet();
		for (Entry<String, String[]> entry : entrySet) {
			String name=entry.getKey();
			if (-1!=name.indexOf("methodName:")) {
				methodName=name.replace("methodName:", "");
				break;
			}
		}
		
		return methodName;
	}
}

3)创建CalAction类(CalAction提供一组加减乘除的方法)
CalAction extends DispatcherAction
提供一组与execute方法的参数、返回值相同的方法,只有方法名不一样

package com.zhouzhuolin.mvc.action;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zhouzhuolin.mvc.framework.DispatcherAction;

public class CalAction extends DispatcherAction {
	
//	+
	public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		int a=Integer.parseInt(req.getParameter("a"));
		int b=Integer.parseInt(req.getParameter("b"));
		int rs=a+b;
		
		req.getSession().setAttribute("rs", rs);
		return "rs";
	}
	
//	-
	public String minus(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		int a=Integer.parseInt(req.getParameter("a"));
		int b=Integer.parseInt(req.getParameter("b"));
		int rs=a-b;
		
		req.getSession().setAttribute("rs", rs);
		return "rs";
	}
	
//	*
	public String mod(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		int a=Integer.parseInt(req.getParameter("a"));
		int b=Integer.parseInt(req.getParameter("b"));
		int rs=a*b;
		
		req.getSession().setAttribute("rs", rs);
		return "rs";
	}
	
//	/
	public String div(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		int a=Integer.parseInt(req.getParameter("a"));
		int b=Integer.parseInt(req.getParameter("b"));
		int rs=a/b;
		
		req.getSession().setAttribute("rs", rs);
		return "rs";
	}

}

三、反射增强第三步:利用ModelDriver接口对Java对象进行赋值

1)利用反射机制对Java对象进行属性赋值
简化调用:BeanUtils.populate(calBean, parameterMap);

private void setReqCal(Action action,HttpServletRequest req) throws IllegalAccessException, InvocationTargetException {
		if (action instanceof DriverModel) {
			DriverModel driverModel=(DriverModel) action;
			Object model = driverModel.getModel();
			Map<String, String[]> parameterMap = req.getParameterMap();
			BeanUtils.populate(model, parameterMap);
			System.out.println(model);
		}
	}

2)ModelDriver接口返回的对象不能为空

package com.zhouzhuolin.mvc.framework;

public interface DriverModel<T> {
	
	public T getModel();
	

}

注1:Action多例模式?因为Action的属性要用来接收参数

CalBean

package com.zhouzhuolin.mvc.entity;

public class CalBean {
	
	private int a;
	
	private int b;

	public int getA() {
		return a;
	}

	public void setA(int a) {
		this.a = a;
	}

	public int getB() {
		return b;
	}

	public void setB(int b) {
		this.b = b;
	}

	public CalBean() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public String toString() {
		return "CalBean [a=" + a + ", b=" + b + "]";
	}

}

增强CalAction

package com.zhouzhuolin.mvc.action;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zhouzhuolin.mvc.entity.CalBean;
import com.zhouzhuolin.mvc.framework.DispatcherAction;
import com.zhouzhuolin.mvc.framework.DriverModel;

public class CalAction extends DispatcherAction implements DriverModel<CalBean> {
	
	private CalBean calBean = new CalBean();
	@Override
	public CalBean getModel() {
		return calBean;
	}
	
//	+
	public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//		int a=Integer.parseInt(req.getParameter("a"));
//		int b=Integer.parseInt(req.getParameter("b"));
		int rs=calBean.getA()+calBean.getB();
		
		req.getSession().setAttribute("rs", rs);
		return "rs";
	}
	
//	-
	public String minus(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//		int a=Integer.parseInt(req.getParameter("a"));
//		int b=Integer.parseInt(req.getParameter("b"));
		int rs=calBean.getA()-calBean.getB();
		
		req.getSession().setAttribute("rs", rs);
		return "rs";
	}
	
//	*
	public String mod(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//		int a=Integer.parseInt(req.getParameter("a"));
//		int b=Integer.parseInt(req.getParameter("b"));
		int rs=calBean.getA()*calBean.getB();
		
		req.getSession().setAttribute("rs", rs);
		return "rs";
	}
	
//	/
	public String div(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//		int a=Integer.parseInt(req.getParameter("a"));
//		int b=Integer.parseInt(req.getParameter("b"));
		int rs=calBean.getA()/calBean.getB();
		
		req.getSession().setAttribute("rs", rs);
		return "rs";
	}
}

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="calAction.action" method="post">
		
		<label>a:</label><input type="text" name="a"><br>
		<label>b:</label><input type="text" name="b"><br>
		<input type="submit" name="methodName:add" value="+">
		<input type="submit" name="methodName:minus" value="-">
		<input type="submit" name="methodName:mod" value="*">
		<input type="submit" name="methodName:div" value="/">
		
	</form>


</body>
</html>

测试结果

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值