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.什么是MVC?

MVC全名:Model View Controller,其中Model(模型层)、View(视图层)、Controller(控

层)它是一种软件设计典范.

2.框架的演绎过程

1、数据处理Dao(需要多少servlet建多少)

缺点:代码重复太多 ,建的类太多? 以图中的(AddBookServlet /? DeleteBookServlet / EditBookServlet / ListBookServlet)

?增

package com.sg.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 AddBookServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req, resp);
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("增");
	}

}

package com.sg.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/delete")
public class DeleteBookServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req, resp);
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("删");
	}

}

package com.sg.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/edit")
public class EditBookServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req, resp);
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("改");
	}

}

package com.sg.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 ListBookServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req, resp);
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("查");
	}

}

主页面

<%@ 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/add">新增</a>
<a href="${pageContext.request.contextPath }/book/delete">删除</a>
<a href="${pageContext.request.contextPath }/book/edit">修改</a>
<a href="${pageContext.request.contextPath }/book/list">查询</a>
</body>
</html>

结果如下:

???

2、select层?

servlet层

package com.sg.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;


public class BookServlet 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 {
		
		String methodName = req.getParameter("methodName");
		
		if("add".equals(methodName)) {
			add(req,resp);
		}else if("edit".equals(methodName)) {
			edit(req,resp);
		}else if("delete".equals(methodName)) {
			delete(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.load()...");
	}

	private void list(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.list()...");
	}

	private void delete(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.delete()...");
	}

	private void edit(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.edit()...");
	}

	private void add(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.add()...");
	}
	
	
	private void ref(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.ref()...");
	}
	
	
	private void other(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.other()...");
	}
	
}

主页面

<a href="${pageContext.request.contextPath }/book.action?methodName=1">新增</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=2">删除</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=3">修改</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=4">查询</a>

结果如下

??

3、反射优化

servlet层

package com.sg.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 {
	@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) {
			e.printStackTrace();
		}

		
	}

	private void load(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.load()...");
	}

	private void list(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.list()...");
	}

	private void delete(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.delete()...");
	}

	private void edit(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.edit()...");
	}

	private void add(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.add()...");
	}
	
	
	private void ref(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.ref()...");
	}
	
	
	private void other(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.other()...");
	}
	
}

主页面

<a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=ref">关联查询</a>

?结果如下:

??

?三:自定义MVC框架?

1、自定义MVC工作原理图
? ? ? ? ? ? ? *.action ? ? ? ? ? 调度 ? ? ? ? ? 截取*(请求路径名) 处理具体业务逻辑
? ?JSP ---------> Servlet(中央控制器)--------------------->Action(子控制器)--->Model(Dao、DB)

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

中央控制器(DispatchServlet)

package com.sg.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 com.sg.web.BookAction;
import com.sg.web.GoodsAction;

/**
 * 中央控制器
 * @author Administrator
 *	jsp:/book.action/goods.action/order.action...
 */
@WebServlet("*.action")
public class DispatchServlet extends HttpServlet {
//	在当前中央控制器中必然会有所有子控制器的集合
//	缺陷:如果有商品的增删改查-->意味着要改动代码-->代码的设计不够灵活
//	思考:在不改动代码的情况下,中央控制器也能找到对应的子控制器去处理浏览器请求
//	方案:我把加子控制器的逻辑/动作,放到配置文件中完成(Dbutil改连接信息是放在代码中完成/现在是放在Properties文件中完成)
//	放在配置文件中完成的好处在于:代码更加灵活,修改相关信息不用动代码了
//	private Map<String, ActionSupport> actions = new HashMap<>();
//	configModel对象又通过建模的知识,把所有的配置信息给读取过来了
	private ConfigModel configModel = null;
	
	/**
	 * 初始化所有的子控制器到当前的中央控制器中
	 */
	@Override
	public void init() throws ServletException {
//		在集合中就有了一个子控制器
//		actions.put("/book", new BookAction());
//		actions.put("/goods", new GoodsAction());
//		actions.put("/order", new OrderAction());
//		...
		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 {
//		把子控制器与浏览器请求关联起来,"寻找"能够处理请求的子控制器
//		http://localhost:8080/book.action?methodName=add-->BookAction.add();
		/*
		 * 思路
		 * 1.url-->/book
		 * 2.通过/book字符串在actions找到BookAction
		 * 3.调用BookAction的add,想要调用add,实际上只要统一调用execute就可以了
		 */
//		获取到浏览器的请求地址
		String url = req.getRequestURI();
//		url-->/book
		url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
//		通过/book字符串在actions找到BookAction
//		ActionSupport actrion = actions.get(url);
//		在Map中寻找子控制器-->在配置文件中寻找子控制器
		/*
		 * 1.通过/book找到对应的ActionModel对象
		 * 2.通过ActionModel对象拿到类的全路径名com.zking.web.BookAction
		 * 3.反射实例化对象
		 */
		ActionModel actionModel = configModel.pop(url);
//		类的全路径名
		String type = actionModel.getType();
		ActionSupport action = null;
		try {
//			BookAction/GoodsAction/..
			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)
			}
//			执行业务逻辑  bookAction.add方法的返回值 “list”
			/*
			 * 1.书籍新增那么跳转书籍展示页面BookList.jsp	转发
			 * 2.书籍编辑跳转编辑界面BookEdit.jsp			重定向
			 */
			String res = action.execute(req, resp);
			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) {
			e.printStackTrace();
		}
	}
}

子控制器

package com.sg.framework;

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

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

ActionSupport(实现Action接口)

package com.sg.framework;

import java.lang.reflect.Method;

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

/**
 * 作用:能够处理浏览器的“所有”请求。包括add/ref/other...
 * 	
 *
 */
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) {
			e.printStackTrace();
		}
		return res;
	}

}

BookServlet(继承ActionSupport)

package com.sg.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;

/**
 * 为什么要学习自定义MVC框架?关键词 :自定义MVC		框架
 * 之前的开发模式:
 * 	MVC:模型层(Model) 视图层(view) 控制层(controller)
 * 	mvc怎么出现的:各司其职
 * 	餐馆:点菜、收银、炒菜、传菜、收拾桌子卫生	大了
 * 	编码:实体类、数据处理Dao、servlet、jsp	代码量多了
 * 
 * 自定义MVC(演绎过程)
 * 	分析不足:
 * 		1.数据处理Dao		代码思路基本重复(前几次讲到)
 * 		2.servlet		代码思路基本重复
 * 			2.1.doget/dopost,实际上doGet基本用不上
 * 			2.2.实体类参数接受代码冗余(req.getParammeter(“”),尤其当实体类属性多的情况,封装到实体类中..)
 * 			2.3.关于结果页面的跳转(转发、重定向)
 * 				req.getdispather("/index.jsp").forward(req,resp);
 * 				resp.sendredirect("/index.jsp");
 * 		3.jsp		代码思路基本重复(HTML、JS前几次讲到)
 * 	解决方案
 * 		1.通用分页(讲过的)、单表的增删改(优化)
 * 		2.servlet不需要写冗余的代码-》自定义mvc框架
 * 		3.自定义jsp标签
 * 框架:反射+设计模式(极大的减少了代码量,把重复性的代码交给框架完成,让程序员关注点放在项目业务)
 * 		1.通用分页指点+通用的增删改
 * 		2.各层(MC)数据Dao层、控制层代码缩减
 * 		3.前台代码的缩减优化
 * 	
 * 		
 * @author Administrator
 *
 */
//@WebServlet("/book.action")
public class BookServlet 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 {
		/*
		 * 优点:相较于前一种,代码量是减少的,由原来的4个类变成了1个类
		 * 缺点:
		 * 	每一次新增一个方法,都要改动原有逻辑,使代码过于冗余
		 * 	举例:一般当修改的时候,需要做数据回显	load
		 * 思考:
		 * 	不改动原有逻辑,也能实现需求
		 * 解决方案:
		 * 	调用哪一个方法,实际上是取决于methodName,加if不是必要条件
		 * 	直白一点:动态调用methodName方法,并且是当前类实例的methodName方法
		 * 	
		 * 总结:
		 * 	反射可以修复上面改动代码才能解决需求问题的缺陷;
		 * 	反射这段代码,相当于中央控制器,并不直接处理浏览器请求
		 * 			处理浏览器请求的是子控制器
		 * 	
		 * 中央控制器		子控制器
		 * 
		 * 今天的课程目标
		 * 	将昨天的自定义mvc框架原理形成代码,形成框架
		 * 	ActionServlet-->DispatchServlet(Springmvc)
		 * why(思考):
		 * 	1.BookServlet中要做增删改查,那么必须要在doPost方法中写反射动态调用新增方法
		 * 		GoodsServlet要做增删改查,那么必须要在doPost方法中写反射动态调用新增方法
		 * 		结论:反射动态调用新增方法代码是重复的的,但是这段又是必须的,也就是还需要进一步优化
		 * 		优化昨天所说的中央控制器
		 * 	2.对于BookServlet中要做增删改查而言,依然是每一个Servlet都要写doget/doPost方法
		 * 		但是实际上对处理业务有用的代码,往往是我们新加的,只需关注业务(add/delete/...)
		 * 		优化昨天所说的子控制器
		 * 	3.解决昨天遗留的两个问题
		 * 		实体类参数接受代码冗余(req.getParammeter(“”),尤其当实体类属性多的情况,封装到实体类中..)
		 * 			req.getParammeter(“bid”)/req.getParammeter(“bname”)/req.getParammeter(“price”)...
		 * 		关于结果页面的跳转(转发、重定向)
		 * 			req.getdispather("/index.jsp").forward(req,resp);
		 * 			resp.sendredirect("/index.jsp");
		 */	
		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) {
			e.printStackTrace();
		}
//		if("add".equals(methodName)) {
//			add(req,resp);
//		}else if("edit".equals(methodName)) {
//			edit(req,resp);
//		}else if("delete".equals(methodName)) {
//			delete(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.load()...");
	}

	private void list(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.list()...");
	}

	private void delete(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.delete()...");
	}

	private void edit(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.edit()...");
	}

	private void add(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.add()...");
	}
	
	
	private void ref(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.ref()...");
	}
	
	
	private void other(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("bookDao.other()...");
	}
	
	
}

主页面测试代码

中央控制器及子控制器优化
<a href="${pageContext.request.contextPath }/book.action?methodName=add">新增</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=delete">删除</a>

输出结果:

?

?

错误:

?

这个错误是我后面写了页面的跳转但只为add和edit写了所以这会报错?

3、重现参数处理代码冗余的问题?

实体类

package com.sg.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.sg.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 com.sg.web.BookAction;
import com.sg.web.GoodsAction;

/**
 * 中央控制器
 * @author Administrator
 *	jsp:/book.action/goods.action/order.action...
 */
@WebServlet("*.action")
public class DispatchServlet extends HttpServlet {
//	在当前中央控制器中必然会有所有子控制器的集合
//	缺陷:如果有商品的增删改查-->意味着要改动代码-->代码的设计不够灵活
//	思考:在不改动代码的情况下,中央控制器也能找到对应的子控制器去处理浏览器请求
//	方案:我把加子控制器的逻辑/动作,放到配置文件中完成(Dbutil改连接信息是放在代码中完成/现在是放在Properties文件中完成)
//	放在配置文件中完成的好处在于:代码更加灵活,修改相关信息不用动代码了
//	private Map<String, ActionSupport> actions = new HashMap<>();
//	configModel对象又通过建模的知识,把所有的配置信息给读取过来了
	private ConfigModel configModel = null;
	
	/**
	 * 初始化所有的子控制器到当前的中央控制器中
	 */
	@Override
	public void init() throws ServletException {
//		在集合中就有了一个子控制器
//		actions.put("/book", new BookAction());
//		actions.put("/goods", new GoodsAction());
//		actions.put("/order", new OrderAction());
//		...
		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 {
//		把子控制器与浏览器请求关联起来,"寻找"能够处理请求的子控制器
//		http://localhost:8080/book.action?methodName=add-->BookAction.add();
		/*
		 * 思路
		 * 1.url-->/book
		 * 2.通过/book字符串在actions找到BookAction
		 * 3.调用BookAction的add,想要调用add,实际上只要统一调用execute就可以了
		 */
//		获取到浏览器的请求地址
		String url = req.getRequestURI();
//		url-->/book
		url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
//		通过/book字符串在actions找到BookAction
//		ActionSupport actrion = actions.get(url);
//		在Map中寻找子控制器-->在配置文件中寻找子控制器
		/*
		 * 1.通过/book找到对应的ActionModel对象
		 * 2.通过ActionModel对象拿到类的全路径名com.zking.web.BookAction
		 * 3.反射实例化对象
		 */
		ActionModel actionModel = configModel.pop(url);
//		类的全路径名
		String type = actionModel.getType();
		ActionSupport action = null;
		try {
//			BookAction/GoodsAction/..
			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)
			}
//			执行业务逻辑  bookAction.add方法的返回值 “list”
			/*
			 * 1.书籍新增那么跳转书籍展示页面BookList.jsp	转发
			 * 2.书籍编辑跳转编辑界面BookEdit.jsp			重定向
			 */
			String res = action.execute(req, resp);
			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) {
			e.printStackTrace();
		}
	}
}

模型驱动接口(ModelDriver)

package com.sg.framework;

//import com.sg.entity.Book;

/**
 * 模型驱动接口
 * 作用:帮助“中央控制器”完成参数封装的工程
 * 	Book book = new Book();
	book.setBid(req.getParameter("bid"));
	book.setBname(req.getParameter("bname"));
	book.setPrice(req.getParameter("price"));
	book.setAthor(req.getParameter("athor"));
	book.setPublish(req.getParameter("publish"));
	System.out.println(book);
 * @author Administrator
 *
 * @param <T>
 */
public interface ModelDriver<T> {
	/**
	 * GoodsAction-->goods
	 * BookAction-->book
	 * ...
	 * @return
	 */
	T getModel();
}

测试界面代码

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

测试结果:

?

4、解决结果码页面跳转代码冗余问题?

上述所有代码

xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
	
	<!-- 
		在这里每加一个配置,就相当于actions.put("/goods", new GoodsAction());
		这样就解决了代码灵活性的问题
	 -->
	<action path="/book" type="com.sg.web.BookAction">
		<forward name="list" path="/bookList.jsp" redirect="false" />
		<forward name="toEdit" path="/bookEdit.jsp" redirect="true" />
	</action>
	
	<action path="/goods" type="com.sg.web.GoodsAction">
		<forward name="failed" path="/login.jsp" redirect="false" />
		<forward name="success" path="/main.jsp" redirect="true" />
	</action>
	
	<action path="/order" type="com.sg.web.OrderAction">
		<forward name="failed" path="/login.jsp" redirect="false" />
		<forward name="success" path="/main.jsp" redirect="true" />
	</action>
</config>

跳转的界面一? ?(bookEdit)

<%@ 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>
书籍编辑界面
</body>
</html>

跳转的界面二? ? ? ?(bookList)

<%@ 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>
书籍列表页面
</body>
</html>

测试页面代码

解决结果码页面跳转代码冗余问题
<a href="${pageContext.request.contextPath }/book.action?methodName=add">新增</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=toEdit">去往编辑界面</a>

测试结果;

?

?

?

?今天的代码就到此为止了,拜拜勒!!!

  开发测试 最新文章
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:47:18 
 
开发: 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 17:22:21-

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