IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 自定义MVC -> 正文阅读

[开发测试]自定义MVC

目录

思维导图

一.自定义MVC?

二.演绎过程

1、之前的开发模式

2、反射优化

?三.自定义MVC框架

?1、自定义MVC工作原理图

?2、优化中央控制器、优化子控制器

?3、实体类参数接受代码冗余?

?4、关于结果页面的跳转(转发、重定向)?


思维导图

一.自定义MVC?

1.什么是MVC?

MVC全名:Model View Controller,其中Model(模型层)、View(视图层)、Controller(控制层)它是一种软件设计典范.

2、三层架构和MVC的区别?

三层架构是一个经典的分层思想,将开发模式分为三层,每个人专注自己擅长模块即可

MVC是一种设计模式,其目的是让视图和业务逻辑分开

3、MVC结构??

????①、 V(视图层) -->JSP/HTML/freemarker?

? ?②、 C(控制层) -->Servlet/Action/Controller

? ?③、M(模型层) -->entity、dao

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

4、目的

二.演绎过程

1、之前的开发模式

①.绝大多数人采用这种方法做增删改查,需要多少个servlet就建多少

增
package com.ysq.web;

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;
@WebServlet("/book/add")
public class AddServlet extends HttpServlet{
@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 {
		System.out.println("bookDao.add()...");
	}
}

删
package com.ysq.web;
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;
@WebServlet("/book/del")
public class DelServlet extends HttpServlet{
	@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 {
			System.out.println("bookDao.del()...");
		}
}

改
package com.ysq.web;

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;
@WebServlet("/book/upd")
public class UpdServlet extends HttpServlet{
	@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 {
			System.out.println("bookDao.upd()...");
		}
}

查
package com.ysq.web;

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;
@WebServlet("/book/list")
public class ListServlet extends HttpServlet {
	@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 {
			System.out.println("bookDao.list()...");
		}
}

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>
<!-- 绝大多数人开发采用这种方式做增删改查(servlet层) -->
<a href="${pageContext.request.contextPath }/book/add">新增</a>
<a href="${pageContext.request.contextPath }/book/del">删除</a>
<a href="${pageContext.request.contextPath }/book/upd">修改</a>
<a href="${pageContext.request.contextPath }/book/list">查询</a>
</body>
</html>

运行结果如下:

②、少数人采用这种方法做增删改查

select层


package com.ysq.web;
 
import java.io.IOException;
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;

@WebServlet("/book.action")
@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 {
	String methodName = req.getParameter("methodName");
	
	if("add".equals(methodName)) {
		add(req,resp);
	}else if("del".equals(methodName)) {
		del(req,resp);
	}else if("upd".equals(methodName)) {
		upd(req,resp);
	}else if("list".equals(methodName)) {
		list(req,resp);
	}else if("load".equals(methodName)) {
		load(req,resp);
	}
	}
 
	private void load(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.load2()");
 
		
	}
 
	private void list(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.list2()");
		
	}
 
	private void upd(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.upd2()");
		
	}
 
	private void del(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.del2()");
		
	}
 
	private void add(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.add2()");
		
	}
	

}

?JSP页面:

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>
<!-- 少数人开发采用这种方式做增删改查(servlet层) -->
<a href="${pageContext.request.contextPath }/book.action?methodName=add">新增2</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=del">删除2</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=upd">修改2</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=list">查询2</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=load">回显2</a>

</body>
</html>

运行结果如下:

2、反射优化

package com.ysq.web;
 
import java.io.IOException;
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;
 
@WebServlet("/book.action")
public class BookServlet extends HttpServlet{
	//动态调用methodName方法,并且是当前类实例的methodName
	@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 {
	String methodName = req.getParameter("methodName");
	try {
		Method m = this.getClass().getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
	//打开访问权限
		m.setAccessible(true);
		//传值
		m.invoke(this,req,resp);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	}
 
	private void load(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.load2()");
 
		
	}
 
	private void list(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.list2()");
		
	}
 
	private void upd(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.upd2()");
		
	}
 
	private void del(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.del2()");
		
	}
 
	private void add(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.add2()");
		
	}
	
	private void ather(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.ather2()");
		
	}
 

}

?三.自定义MVC框架

?1、自定义MVC工作原理图

?2、优化中央控制器、优化子控制器

①.子控制器(Action接口)? ? 处理浏览器请求

package com.ysq.framework;

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

/**
 * 子控制器
 * 处理浏览器请求
 * 针对于add/del进行抽取,抽象 abstract
 * @author zjjt
 *
 */
public interface Action {
//这一个方法就是add/del进行抽取,抽象方法
	//作用:能够处理浏览器的“所有”请求包括add/del
	//通过返回值来决定跳转哪一个页面(至于是重定向/转发由中央控制器决定)
	public String execute(HttpServletRequest req, HttpServletResponse resp);
	
}

②.ActionSupport(实现Action接口)

package com.ysq.framework;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 作用:能够处理浏览器的“所有”请求包括add/del
 * 
 * @author zjjt
 *
 */
public class ActionSupport implements Action {
	@Override
	public String execute(HttpServletRequest req, HttpServletResponse resp) {
		String methodName = req.getParameter("methodName");
		String res=null;
		try {
			Method m = this.getClass().getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
		//打开访问权限
			m.setAccessible(true);
			//传值
			res=(String) m.invoke(this,req,resp);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return res;
	}

}

③.BookAction(继承ActionSupport)

package com.ysq.web;

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

import com.ysq.entity.Book;
import com.ysq.framework.ActionSupport;
import com.ysq.framework.ModelDriver;

public class BookAction extends ActionSupport implements ModelDriver<Book>{
	public Book book=new Book();
	
@Override
public Book getModel() {
	// TODO Auto-generated method stub
	return book;
}
	//从父类继承了execute方法,就把反射动态调用方法的代码给继承过来了
	//BookAction 就相当于以前的BookServlet
	//当前子控制器在哪里调用?把子控制与浏览器关联起来
	
	private String upd(HttpServletRequest req, HttpServletResponse resp) {
	System.out.println("bookDao.upd3()");
	return "upd";
}

private String add(HttpServletRequest req, HttpServletResponse resp) {

	System.out.println(book);
	System.out.println("bookDao.add3(book)");
	return "del";
	
}
private void del(HttpServletRequest req, HttpServletResponse resp) {
	System.out.println("bookDao.del3()");
	
}
}

④.中央控制器(DispatchServlet)

package com.ysq.framework;

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

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 org.apache.commons.beanutils.BeanUtils;

import com.ysq.web.BookAction;
import com.ysq.web.GoodsAction;
/**
 * 中央控制器
 * @author zjjt
 * jsp:/book.action
 *
 */
@WebServlet("*.action")
public class DispatchServlet extends HttpServlet{
	//在当前中央控制器中必然会有所有子控制器的集合
	private Map<String, ActionSupport> actions=new HashMap<String, ActionSupport>();
	//初始化所有的子控制器到当前的中央控制器中

	public void init() throws ServletException {
//在集合就有了一个子控制器
	//缺陷:如果有商品的增删改查,就要不断的去累积它,意味着要改动代码 代码不够灵活
	try {
    actions.put("/book",new BookAction());
	actions.put("/goods",new GoodsAction());
		
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws                     ServletException, IOException {
	// 把子控制器与浏览器请求关联起来,“寻找”能够处理请求的子控制器
	//http://localhost:8080/book.action?methodName=add
/**思路:
 * 1.url-->book
 * 2.通过book字符串在actions找到BookAction
 * 3.调用BookActions的add 想要掉add 实际上只要统一execute就可以了
 */
	//获取到浏览器的请求地址
	String url = req.getRequestURI();
	url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
	ActionSupport action = actions.get(url);
	action.execute(req, resp);
	
	}
}

因为④代码的缺陷:如果有商品的增删改查,就要不断的去累积它,意味着要改动代码 代码不够灵活,所以对它进行了优化

?⑤.中央控制器(DispatchServlet) 使用到了建模 和所需的jar包

?代码如下:

package com.ysq.framework;

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

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 org.apache.commons.beanutils.BeanUtils;

import com.ysq.web.BookAction;
import com.ysq.web.GoodsAction;
/**
 * 中央控制器
 * @author zjjt
 * jsp:/book.action
 *
 */
@WebServlet("*.action")
public class DispatchServlet extends HttpServlet{
	//在当前中央控制器中必然会有所有子控制器的集合
	//private Map<String, ActionSupport> actions=new HashMap<String, ActionSupport>();
	private ConfigModel configModel=null;
	
	//初始化所有的子控制器到当前的中央控制器中
@Override
	public void init() throws ServletException {
//在集合就有了一个子控制器
	//缺陷:如果有商品的增删改查,就要不断的去累积它,意味着要改动代码 代码不够灵活
	//思考:在bu改变代码的情况下,中央控制器也能找到对应的子控制器去处理浏览器的请求
	//方案:把加子控制器的逻辑/动作,放到配置文件中完成
	//放在配置文件中完成的好处在于:代码更加灵活,修改信息不要动代码了
	//configModel对象又通过建模的知识,把所有的配置信息给读取出来了
/*	actions.put("/book",new BookAction());
	actions.put("/goods",new GoodsAction());*/
	try {
		configModel=ConfigModelFactory.build();
	} 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 {
		// 把子控制器与浏览器请求关联起来,“寻找”能够处理请求的子控制器
	//http://localhost:8080/book.action?methodName=add
/**思路:
 * 1.url-->book
 * 2.通过book字符串在actions找到BookAction
 * 3.调用BookActions的add 想要掉add 实际上只要统一execute就可以了
 */
	//获取到浏览器的请求地址
	String url = req.getRequestURI();
	url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
	//ActionSupport action = actions.get(url);
	//action.execute(req, resp);
	//原来在map中寻找子控制器 现在在配置文件中找子控制器
	
	/**
	 * 1.通过/book找到对应的ActionModel对象
	 * 2.通过ActionModel对象拿到类的全路径名com.zy.web.BookAction
	 * 3.反射实例化对象
	 * 
	 */
	ActionModel actionModel = configModel.pop(url);
	//拿到全路径名
	String type = actionModel.getType();
	ActionSupport action=null;
	try {
	   action= (ActionSupport) Class.forName(type).newInstance();
		action.execute(req, resp);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	}

}

测试:

<%@ 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>

<!-- 中央控制器及子控制器优化 -->
<a href="${pageContext.request.contextPath }/book.action?methodName=add">新增3</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=del">删除3</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=upd">修改3</a>

</body>
</html>

运行结果如下:

?3、实体类参数接受代码冗余?

①、Book(实体类)

package com.ysq.entity;

public class Book {
	  public String bid;
	  public String bname;
	  public String price;
	  public String athor;
	  public String publish;
	public String getBid() {
		return bid;
	}
	public void setBid(String bid) {
		this.bid = bid;
	}
	public String getBname() {
		return bname;
	}
	public void setBname(String bname) {
		this.bname = bname;
	}
	public String getPrice() {
		return price;
	}
	public void setPrice(String price) {
		this.price = price;
	}
	public String getAthor() {
		return athor;
	}
	public void setAthor(String athor) {
		this.athor = athor;
	}
	public String getPublish() {
		return publish;
	}
	public void setPublish(String publish) {
		this.publish = publish;
	}
	@Override
	public String toString() {
		return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + ", athor=" + athor + ", publish="
				+ publish + "]";
	}
	
	

}

②、DispatchServlet?


package com.ysq.framework;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
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 org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.dom4j.DocumentException;
import com.ysq.servlet.BookAction;
import com.ysq.servlet.GoodsAaction;
/**
 * 中央控制器
 *jsp:/book.action/goods.action
 */
@WebServlet("*.action")
public class DispatchServlet extends HttpServlet{
	private ConfigModel configModel=null;
	@Override
	public void init() throws ServletException {
		try {
			configModel=ConfigModelFactory.build();
		} catch (Exception e) {
			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 {
		//获取到浏览器的请求地址
		String uri = req.getRequestURI();
		uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
		ActionModel actionModel = configModel.pop(uri);
		String type = actionModel.getType();
		ActionSupport action;
		try {
			action = (ActionSupport) Class.forName(type).newInstance();
			//完成实体参数封装
			//执行业务逻辑
			if(action instanceof ModelDriver) {
				//当前子控制器实现了模型驱动接口
				ModelDriver m=(ModelDriver) action;
				//Book/Goods/...
				Object bean = m.getModel();
				//所有请求参数都在这,需要将所有的请求参数封装到Book/Goods
				BeanUtils.populate(bean, req.getParameterMap());
				//PropertyUtils.getProperty(bean, name);
			}
			action.execute(req, resp);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}	

}

③、ModelDriver<T>

package com.ysq.framework;
/**
 * 模型驱动接口
 * 作用:帮助“中央控制器”完成参数封装工程
 * @author zjjt
 *
 */
public interface ModelDriver<T> {
	
		T getModel();

}

④、?BookAction (extends ActionSupport implements ModelDriver<Book>)

package com.ysq.web;

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

import com.ysq.entity.Book;
import com.ysq.framework.ActionSupport;
import com.ysq.framework.ModelDriver;

public class BookAction extends ActionSupport implements ModelDriver<Book>{
	public Book book=new Book();
	
@Override
public Book getModel() {
	// TODO Auto-generated method stub
	return book;
}
	//从父类继承了execute方法,就把反射动态调用方法的代码给继承过来了
	//BookAction 就相当于以前的BookServlet
	//当前子控制器在哪里调用?把子控制与浏览器关联起来
	
	private void upd(HttpServletRequest req, HttpServletResponse resp) {
	System.out.println("bookDao.upd3()");	
    }
 
private void del(HttpServletRequest req, HttpServletResponse resp) {
	System.out.println("bookDao.del3()");	
    }
 
private void add(HttpServletRequest req, HttpServletResponse resp) {	
	System.out.println("bookDao.add3(book)");	
    }

}

⑤、测试界面

<!--重复参数处理代码冗余的问题 -->
<form action="${pageContext.request.contextPath }/book.action?methodName=add" method="post">
?? ?书籍ID:<input type="text" name="bid" value="1">
?? ?书籍名称:<input type="text" name="bname" value="2">
?? ?书籍价格:<input type="text" name="price" value="24">
?? ?书籍作者:<input type="text" name="athor" value="5">
?? ?书籍出版社:<input type="text" name="publish" value="9">
?? ?<input type="submit">
</form>

运行结果如下:

?4、关于结果页面的跳转(转发、重定向)?

①.Action

package com.ysq.framework;

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

/**
 * 子控制器
 * 处理浏览器请求
 * 针对于add/del进行抽取,抽象 abstract
 * @author zjjt
 *
 */
public interface Action {
//这一个方法就是add/del进行抽取,抽象方法
	//作用:能够处理浏览器的“所有”请求包括add/del
	//通过返回值来决定跳转哪一个页面(至于是重定向/转发由中央控制器决定)
	public String execute(HttpServletRequest req, HttpServletResponse resp);
	
}

②.ActionSupport

package com.ysq.framework;
 
import java.lang.reflect.Method;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 作用:能够处理浏览器的“所有”请求包括add/del
 * 
 * @author zjjt
 *
 */
public class ActionSupport implements Action {
	@Override
	public String execute(HttpServletRequest req, HttpServletResponse resp) {
		String methodName = req.getParameter("methodName");
		String res=null;
		try {
			Method m = this.getClass().getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
		//打开访问权限
			m.setAccessible(true);
			//传值
			res=(String) m.invoke(this,req,resp);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return res;
	}
 

}

③BookAction


package com.ysq.web;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import com.zy.entity.Book;
import com.zy.framework.ActionSupport;
import com.zy.framework.ModelDriver;
 
public class BookAction extends ActionSupport implements ModelDriver<Book>{
	public Book book=new Book();
	
@Override
public Book getModel() {
	// TODO Auto-generated method stub
	return book;
}
	//从父类继承了execute方法,就把反射动态调用方法的代码给继承过来了
	//BookAction 就相当于以前的BookServlet
	//当前子控制器在哪里调用?把子控制与浏览器关联起来
	
	private String upd(HttpServletRequest req, HttpServletResponse resp) {
	System.out.println("bookDao.upd3()");
	return "upd";
}
 
private String add(HttpServletRequest req, HttpServletResponse resp) {
 
	System.out.println(book);
	System.out.println("bookDao.add3(book)");
	return "del";
	
}
private void del(HttpServletRequest req, HttpServletResponse resp) {
	System.out.println("bookDao.del3()");
	
}

}

④DispatchServlet?


package com.ysq.framework;
 
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 
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 org.apache.commons.beanutils.BeanUtils;
 
import com.ysq.web.BookAction;
import com.ysq.web.GoodsAction;
/**
 * 中央控制器
 * @author zjjt
 * jsp:/book.action
 *
 */
@WebServlet("*.action")
public class DispatchServlet extends HttpServlet{
	//在当前中央控制器中必然会有所有子控制器的集合
	//private Map<String, ActionSupport> actions=new HashMap<String, ActionSupport>();
	private ConfigModel configModel=null;
	
	//初始化所有的子控制器到当前的中央控制器中
@Override
	public void init() throws ServletException {
//在集合就有了一个子控制器
	//缺陷:如果有商品的增删改查,就要不断的去累积它,意味着要改动代码 代码不够灵活
	//思考:在bu改变代码的情况下,中央控制器也能找到对应的子控制器去处理浏览器的请求
	//方案:把加子控制器的逻辑/动作,放到配置文件中完成
	//放在配置文件中完成的好处在于:代码更加灵活,修改信息不要动代码了
	//configModel对象又通过建模的知识,把所有的配置信息给读取出来了
/*	actions.put("/book",new BookAction());
	actions.put("/goods",new GoodsAction());*/
	try {
		configModel=ConfigModelFactory.build();
	} 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 {
		// 把子控制器与浏览器请求关联起来,“寻找”能够处理请求的子控制器
	//http://localhost:8080/book.action?methodName=add
/**思路:
 * 1.url-->book
 * 2.通过book字符串在actions找到BookAction
 * 3.调用BookActions的add 想要掉add 实际上只要统一execute就可以了
 */
	//获取到浏览器的请求地址
	String url = req.getRequestURI();
	url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
	//ActionSupport action = actions.get(url);
	//action.execute(req, resp);
	//原来在map中寻找子控制器 现在在配置文件中找子控制器
	
	/**
	 * 1.通过/book找到对应的ActionModel对象
	 * 2.通过ActionModel对象拿到类的全路径名com.zy.web.BookAction
	 * 3.反射实例化对象
	 * 
	 */
	ActionModel actionModel = configModel.pop(url);
	//拿到全路径名
	String type = actionModel.getType();
	ActionSupport action=null;
	try {
		//如 BookAction
	   action= (ActionSupport) Class.forName(type).newInstance();
	   //完成实体类参数的封装
	   if(action instanceof ModelDriver) {
		   //当前子控制器实现了模型驱动接口
		   ModelDriver m=(ModelDriver) action;
		   //Book
		   Object bean = m.getModel();
		   //所有的请求参数都在这,需要将所有的请求参数封装到Book/Goods/
		  BeanUtils.populate(bean, req.getParameterMap());
		   
	   }
	   //执行业务逻辑  bookAction.add方法返回值del
	   /**
	    * 1.书籍新增那么跳转为书籍del.jsp  转发
	    * 2.书籍修改跳book.jsp  重定向
	    */
		String res = action.execute(req, resp);
		//res就是返回值
		ForwardModel forwardModel = actionModel.pop(res);
		String path = forwardModel.getPath();
		boolean isredirect = forwardModel.isRedirect();
		//是重定向
		if(isredirect) {
			resp.sendRedirect(req.getContextPath()+path);
		}else {
			req.getRequestDispatcher(path).forward(req, resp);
		}
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	}

}

⑤config.xml

<?xml version="1.0" encoding="UTF-8"?>
 
<!-- config标签:可以包含0~N个action标签 -->
<config>
	<!-- action标签:可以饱含0~N个forward标签 path:以/开头的字符串,并且值必须唯一 非空 type:字符串,非空 -->
	
 
	
	<!-- 在这里每加一个配置,就相当于写了 actions.put("/goods",new GoodsAction());这样就解决了代码灵活性问题  false代表转发-->
	<action path="/book" type="com.ysq.web.BookAction">
		<forward name="del" path="/del.jsp" redirect="false" />
		<forward name="upd" path="/book.jsp" redirect="true" />
	</action>
</config>

⑥测试

<%@ 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="${pageContext.request.contextPath }/book.action?methodName=add" method="post">	
	<!-- -->
	<a href="${pageContext.request.contextPath }/book.action?methodName=add">新增4</a>
	<a href="${pageContext.request.contextPath }/book.action?methodName=upd">修改4</a>
</form>
</body>
</html>

运行结果如下:

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-31 15:45:12  更:2021-08-31 15:46:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 5:11:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码