J2EE之自定义MVC框架知识(中篇)

2023-11-10

J2EE之自定义MVC框架知识(中篇)

文章目录

前言

在上期J2EE之自定义MVC框架知识(上篇)中我们了解了一些自定义MVC框架在我们开发编程中带来的一些方便,但基于上篇博客中自定义MVC框架优化的代码还有可优化之处,这期J2EE之自定义MVC框架知识(中篇)将针对上期的博客代码进行进一步优化。让我们跟着思维导图一起来学习了解一下吧。

在这里插入图片描述

1.优化中央控制器中的action容器,使其加载变成可配置的

1.1 编写.xml文件(config.xml)

创建一个源文件夹(Source Folder)文件路径如下

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<!-- config标签:可以包含0~N个action标签 -->
	
<!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) 'true'
>

]>

<config>
	<!-- action标签:可以饱含0~N个forward标签 path:以/开头的字符串,并且值必须唯一 非空 ,子控制器对应的路径 type:字符串,非空,子控制器的完整类名 -->
	<action path="/book" type="com.YX.Web.BookAction">
		<forward name="success" path="/index.jsp" redirect="true" />
		<forward name="failed" path="/register.jsp" redirect="false" />
	</action>
	<action path="/order" type="com.YX.Web.OrderAction">
		<forward name="a" path="/index.jsp" redirect="false" />
		<forward name="b" path="/welcome.jsp" redirect="true" />
	</action>
</config>

1.2 导入XML建模相关的类

文件路径展示图

在这里插入图片描述

ActionModel类
package com.YX.framework.model;

import java.util.HashMap;
import java.util.Map;


/**
 * @author 君易--鑨
 * 2023年7月2日下午8:47:58
 * 
 */
public class ActionModel {
	private String path;
	private String type;
	private Map<String, ForwardModel> fMap = new HashMap<String, ForwardModel>();
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
//	将forward往action中放 压栈
	public void push(ForwardModel forwardModel) {
		fMap.put(forwardModel.getName(), forwardModel);
	}
	
//	从action中通过name值取出forward
	public ForwardModel pop(String name) {
		return fMap.get(name);
	}
	
}

ConfigModel类
package com.YX.framework.model;

import java.util.HashMap;
import java.util.Map;
/**
 * @author 君易--鑨
 * 2023年7月2日下午8:47:58
 * 
 */
public class ConfigModel {
	private Map<String, ActionModel> aMap = new HashMap<String, ActionModel>();
	
	public void push(ActionModel actionModel) {
		aMap.put(actionModel.getPath(), actionModel);
	}
	
	public ActionModel pop(String path) {
		return aMap.get(path);
	}
	
	public static void main(String[] args) throws Exception {
		ConfigModel configModel = ConfigModelFactory.build();
		ActionModel actionModel = configModel.pop("/loginAction");
		ForwardModel forwardModel = actionModel.pop("success");
		System.out.println(forwardModel.getPath());
	}
}

ConfigModelFactory类
package com.YX.framework.model;
import java.io.InputStream;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;


/**23种设计模式--工厂模式--创建型模式
 * build/newinstance
 * @author 君易--鑨
 * 2023年7月2日下午8:50:10
 * 
 */
public class ConfigModelFactory {
	public static ConfigModel build(String xmlPath) throws Exception {

		ConfigModel configModel = new ConfigModel();
		
		InputStream in = ConfigModelFactory.class.getResourceAsStream(xmlPath);
		SAXReader sr = new SAXReader();
		Document doc = sr.read(in);
//		configModel要有类容,就意味着actionmodel要有类容,然后放入到configmodel中去
		List<Element> actionEles = doc.selectNodes("/config/action");
		for (Element actionEle : actionEles) {
//			System.out.println(actionEle.asXML());
			ActionModel actionModel = new ActionModel();
			actionModel.setPath(actionEle.attributeValue("path"));
			actionModel.setType(actionEle.attributeValue("type"));
//			actionModel要有forwardModel,就意味着forwardmodel要有类容,然后放入到actionmodel中去
			List<Element> forwardEles = actionEle.selectNodes("forward");
			
			for (Element forwardEle : forwardEles) {
				System.out.println(forwardEle.asXML());
				ForwardModel forwardModel = new ForwardModel();
				forwardModel.setName(forwardEle.attributeValue("name"));
				forwardModel.setPath(forwardEle.attributeValue("path"));
//				只有填写false才是转发,其它都为重定向
//				forwardModel.setRedirect(false);
				forwardModel.setRedirect(!"false".equals(forwardEle.attributeValue("redirect")));
				
				actionModel.push(forwardModel);
			}
			
			
			configModel.push(actionModel);
		}
		
		return configModel;
	
	}
	
	
	public static ConfigModel build() throws Exception {
		return build("/config.xml");
	}
	
	public static void main(String[] args) throws Exception {
		ConfigModelFactory.build();
	}
}

ForwardModel类
package com.YX.framework.model;
/**
 * @author 君易--鑨
 * 2023年7月2日下午8:47:58
 * 
 */
public class ForwardModel {
//	name、path、redirect
	private String name;
	private String path;
	private boolean redirect;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public boolean isRedirect() {
		return redirect;
	}
	public void setRedirect(boolean redirect) {
		this.redirect = redirect;
	}
	
}

1.3 创建一个OrderAction类(用于测试效果)

package com.YX.Web;

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

import com.YX.framework.Action;

/**订单操作方法类
 * @author 君易--鑨
 * 2023年7月2日下午8:53:06
 * 
 */
public class OrderAction extends Action{
     
	/**
	 * 新增的方法
	 * 
	 * @param request
	 * @param response
	 */
	public void add(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了OrderAction新增的方法........");
	}

	/**
	 * 删除的方法
	 * 
	 * @param request
	 * @param response
	 */
	public void del(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了OrderAction删除的方法........");
	}

	/**
	 * 修改的方法
	 * 
	 * @param request
	 * @param response
	 */
	public void upd(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了OrderAction修改的方法........");
	}

	/**
	 * 查看的方法
	 * 
	 * @param request
	 * @param response
	 */
	public void list(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了OrderAction查看的方法........");

	}
}

1.4 DispatherServlet类的代码优化

package com.YX.framework;

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

import javax.management.RuntimeErrorException;
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 com.YX.Web.BookAction;
import com.YX.Web.OrderAction;
import com.YX.framework.model.ActionModel;
import com.YX.framework.model.ConfigModel;
import com.YX.framework.model.ConfigModelFactory;

/**
 * 中央控制器
 * 
 * @author 君易--鑨 2023年6月29日下午10:20:15
 * 
 */
@WebServlet("*.do")
public class DispatherServlet extends HttpServlet {

//	public Map<String, Action> actionMap = new HashMap<String, Action>();
//   以前所有的子控制器释放到map集合中,现在所有的子控制器在mvc.xml中,其实就是放到模型对象中
	private ConfigModel configmodle;
	@Override
	public void init() throws ServletException {
//		actionMap.put("/book", new BookAction());
//		actionMap.put("/order", new OrderAction());
	   try {
//		   configmodle包含了所有的子控制器
		configmodle=ConfigModelFactory.build();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 拿到访问路径
		String uri = request.getRequestURI();
		// 截取获取路径
		uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
		// 获取对应的操作的方法类
//		Action action = actionMap.get(uri);
//		要通过uri=/book,在configmodle对象中找
		ActionModel actionModel = configmodle.pop(uri);
		if (actionModel==null) {
			throw new RuntimeException("action not config");
		}
//		com.zking.Web.BookAction
		String type = actionModel.getType();
//		反射实例化对象==BookAction bookaction=new BookAction();
		Action action;
		try {
			action = (Action) Class.forName(type).newInstance();
			// 调用识别方法类的方法
			action.execute(request, response);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 

	}
}

1.5 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>

<p>自定义MVCk框架02  </p>
<a href="order.do?methodname=add">订单新增</a>
<a href="order.do?methodname=del">订单删除</a>
<a href="order.do?methodname=upd">订单修改</a>
<a href="order.do?methodname=list">订单查看</a>
<a href="book.do?methodname=add">书籍新增</a>
<a href="book.do?methodname=del">书籍删除</a>
<a href="book.do?methodname=upd">书籍修改</a>
<a href="book.do?methodname=list">书籍查看</a>


</body>
</html>
页面显示

在这里插入图片描述

点击功能控制台模拟输出结果(以订单查看、书籍删除为例)

在这里插入图片描述

1.6 注意事项:

  1. 实现对应操作功能之前确保.xml文件配置好了。

如下图中的功能

在这里插入图片描述

.xml文件配置图讲解(config.xml)

在这里插入图片描述

2.如果实现对应操作功能时.xml文件未配置。(案例如下)

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>

<p>自定义MVCk框架02  </p>
<a href="order.do?methodname=add">订单新增</a>
<a href="order.do?methodname=del">订单删除</a>
<a href="order.do?methodname=upd">订单修改</a>
<a href="order.do?methodname=list">订单查看</a>
<a href="book.do?methodname=add">书籍新增</a>
<a href="book.do?methodname=del">书籍删除</a>
<a href="book.do?methodname=upd">书籍修改</a>
<a href="book.do?methodname=list">书籍查看</a>
<a href="good.do?methodname=list">商品查看</a>

</body>
</html>

页面显示

在这里插入图片描述

在这里插入图片描述

如果点击商品查看功能页面显示

在这里插入图片描述

1.7 弊端

中央控制器中的action容器配置不能灵活配置

2.针对反射调用的业务代码,优化页面跳转代码(以BookAction为例)

2.1 优化Action类代码

package com.YX.framework;

import java.io.IOException;
import java.lang.reflect.Method;

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

/**
 * 子控制器(真正实现功能) 各操作方法的父类
 * 
 * @author 君易--鑨 2023年6月29日下午9:48:19
 * 
 */
public class Action {
	protected String execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 获取页面传来的方法参数,用于辨别执行对应操作的方法
		String methodName = request.getParameter("methodname");
		// 定义一个空变量接受方法结果
		String res = "";
		// 反射从获取类类开始 this:代表BookServlet类
		try {
			// 获取当前类的方法对象
			Method sclass = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,
					HttpServletResponse.class);
			// 打开访问权限
			sclass.setAccessible(true);
			// 执行对应方法名对象的方法
			// 变量接受方法结果
			res = (String) sclass.invoke(this, request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return res;

	}
}

2.2 优化BookAction类代码

package com.YX.Web;

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

import com.YX.framework.Action;


/**对应表的操作方法类
 * @author 君易--鑨
 * 2023年6月29日下午10:40:48
 * 
 */
public class BookAction extends Action{
  
	//tolist:代表重定向;list:代表转发。
	/**
	 * 新增的方法
	 * 
	 * @param request
	 * @param response
	 */
	public String add(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了BookAction新增的方法........");
		request.setAttribute("content", "君易--鑨");
		return "tolist";
	}

	/**
	 * 删除的方法
	 * 
	 * @param request
	 * @param response
	 */
	public String del(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了BookAction删除的方法........");
		request.setAttribute("content", "君易--鑨");
		return "tolist";
		
	}

	/**
	 * 修改的方法
	 * 
	 * @param request
	 * @param response
	 */
	public String upd(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了BookAction修改的方法........");
		request.setAttribute("content", "君易--鑨");
		return "tolist";
	}

	/**
	 * 查看的方法
	 * 
	 * @param request
	 * @param response
	 */
	public String list(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了BookAction查看的方法........");
		request.setAttribute("content", "君易--鑨");
		return "list";

	}
}

2.3 修改.xml文件(config.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!-- config标签:可以包含0~N个action标签 -->
	
<!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) 'true'
>

]>


<config>
	<!-- action标签:可以饱含0~N个forward标签 path:以/开头的字符串,并且值必须唯一 非空 ,子控制器对应的路径 type:字符串,非空,子控制器的完整类名 -->
	<action path="/book" type="com.YX.Web.BookAction">
	<forward name="list" path="/res.jsp" redirect="false" />
		<forward name="tolist" path="/res.jsp" redirect="true" />
	</action>
	<action path="/order" type="com.YX.Web.OrderAction">
	</action>
</config>

在这里插入图片描述

2.4 创建重定向和转发的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>
跳转成功,携带数据:${content }
</body>
</html>

2.5 优化DispatherServlet代码

package com.YX.framework;

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;

import com.YX.framework.model.ActionModel;
import com.YX.framework.model.ConfigModel;
import com.YX.framework.model.ConfigModelFactory;
import com.YX.framework.model.ForwardModel;

/**
 * 中央控制器
 * 
 * @author 君易--鑨 2023年6月29日下午10:20:15
 * 
 */
@WebServlet("*.do")
public class DispatherServlet extends HttpServlet {

//	public Map<String, Action> actionMap = new HashMap<String, Action>();
//   以前所有的子控制器释放到map集合中,现在所有的子控制器在mvc.xml中,其实就是放到模型对象中
	private ConfigModel configmodle;
	@Override
	public void init() throws ServletException {
//		actionMap.put("/book", new BookAction());
//		actionMap.put("/order", new OrderAction());
	   try {
//		   configmodle包含了所有的子控制器
		configmodle=ConfigModelFactory.build();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 拿到访问路径
		String uri = request.getRequestURI();
		// 截取获取路径
		uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
		// 获取对应的操作的方法类
//		Action action = actionMap.get(uri);
//		要通过uri=/book,在configmodle对象中找
		ActionModel actionModel = configmodle.pop(uri);
		if (actionModel==null) {
			throw new RuntimeException("action not config");
		}
//		com.zking.Web.BookAction
		String type = actionModel.getType();
//		反射实例化对象==BookAction bookaction=new BookAction();
		Action action;
		try {
			action = (Action) Class.forName(type).newInstance();
			// 调用识别方法类的方法
//			具体业务代码执行后的返回值add/del/upd/list的返回值==》list/tolist
			String res = action.execute(request, response);
//			通过返回值拿到,该方法结果是重定向还是转发那个页面
			ForwardModel forwardModel = actionModel.pop(res);
			if (forwardModel!=null) {
				boolean redirect = forwardModel.isRedirect();
				System.out.println(redirect);
				String path=forwardModel.getPath();
				if (redirect) {
					response.sendRedirect(request.getContextPath()+"/"+path);
				}else {
					request.getRequestDispatcher(path).forward(request, response);
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
}

2.6 测试结果

增删改是重定向,查看是转发。

重定向页面输出结果和控制台输出结果

在这里插入图片描述

在这里插入图片描述

转发页面输出结果和控制台输出结果

在这里插入图片描述

在这里插入图片描述

2.7 弊端:

jsp传递到后台,封装到实体类的代码过多

2.8 注意事项:

在这里插入图片描述

如果画横线的代码是下面这样拼接的话

response.sendRedirect(path);

再jsp页面上实现增删改是跳转页面会出现下面这种情况

在这里插入图片描述

3.优化jsp页面参数传递后台的代码

3.1创建一个对应表的实体类(以Book类为例)

Book类代码
package com.YX.entity;

/**
 * 实体类:书籍类
 * 
 * @author 君易--鑨 2023年7月3日上午12:30:00
 * 
 */
public class Book {
	// 定义属性
	private int bid;
	private int bname;
	private float price;

	/**
	 * 无参构造
	 */
	public Book() {
		// TODO Auto-generated constructor stub
	}

	// 获取属性对应的get、set方法
	public int getBid() {
		return bid;
	}

	public void setBid(int bid) {
		this.bid = bid;
	}

	public int getBname() {
		return bname;
	}

	public void setBname(int bname) {
		this.bname = bname;
	}

	public float getPrice() {
		return price;
	}

	public void setPrice(float price) {
		this.price = price;
	}

	/**
	 * 有参构造
	 * 
	 * @param bid
	 * @param bname
	 * @param price
	 */
	public Book(int bid, int bname, float price) {
		super();
		this.bid = bid;
		this.bname = bname;
		this.price = price;
	}

	// 实体对象信息输出语句体
	@Override
	public String toString() {
		return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
	}

}

3.2 创建一个接口类(所有的子控制器通用)

ModelDriver类
package com.YX.framework;

/**模型驱动接口
 * @author 君易--鑨
 * 2023年7月3日上午12:54:36
 * 
 */
public interface ModelDriver<T> {
    
	T getModel();
}

3.3 优化子控制器代码(BookAction为例)

BookAction类
package com.YX.Web;

import java.util.Map;

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

import com.YX.entity.Book;
import com.YX.framework.Action;
import com.YX.framework.ModelDriver;


/**对应表的操作方法类
 * @author 君易--鑨
 * 2023年6月29日下午10:40:48
 * 
 */
public class BookAction extends Action implements ModelDriver<Book>{
  
	//tolist:代表重定向;list:代表转发。
	/**
	 * 新增的方法
	 * 
	 * @param request
	 * @param response
	 */
//	实例化实体类
   private Book book=new Book();
	public String add(HttpServletRequest request, HttpServletResponse response) {
/*
 * 1.要有表的内属性对象
 * 2.获取到所有的参数及参数getParameterMap()
 * 3.将参数值封装到表对应的对象中
 * 4.实现通用
 */
		//      获取到所有的请求参数值
		Map<String, String[]> parameterMap = request.getParameterMap();
		
		System.out.println("调用了BookAction新增的方法........");
		request.setAttribute("content", "君易--鑨");
		return "tolist";
	}

	/**
	 * 删除的方法
	 * 
	 * @param request
	 * @param response
	 */
	public String del(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了BookAction删除的方法........");
		request.setAttribute("content", "君易--鑨");
		return "tolist";
		
	}

	/**
	 * 修改的方法
	 * 
	 * @param request
	 * @param response
	 */
	public String upd(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了BookAction修改的方法........");
		request.setAttribute("content", "君易--鑨");
		return "tolist";
	}

	/**
	 * 查看的方法
	 * 
	 * @param request
	 * @param response
	 */
	public String list(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了BookAction查看的方法........");
		request.setAttribute("content", "君易--鑨");
		return "list";

	}

	@Override
	public Book getModel() {
		return book;
	}
}

3.4 优化中央控制器的代码

DispatherServlet类
package com.YX.framework;

import java.io.IOException;
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.YX.framework.model.ActionModel;
import com.YX.framework.model.ConfigModel;
import com.YX.framework.model.ConfigModelFactory;
import com.YX.framework.model.ForwardModel;

/**
 * 中央控制器
 * 
 * @author 君易--鑨 2023年6月29日下午10:20:15
 * 
 */
@WebServlet("*.do")
public class DispatherServlet extends HttpServlet {

//	public Map<String, Action> actionMap = new HashMap<String, Action>();
//   以前所有的子控制器释放到map集合中,现在所有的子控制器在mvc.xml中,其实就是放到模型对象中
	private ConfigModel configmodle;
	@Override
	public void init() throws ServletException {
	   try {
//		   configmodle包含了所有的子控制器
		configmodle=ConfigModelFactory.build();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 拿到访问路径
		String uri = request.getRequestURI();
		// 截取获取路径
		uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
		// 获取对应的操作的方法类
//		Action action = actionMap.get(uri);
//		要通过uri=/book,在configmodle对象中找
		ActionModel actionModel = configmodle.pop(uri);
		if (actionModel==null) {
			throw new RuntimeException("action not config");
		}
//		com.zking.Web.BookAction
		String type = actionModel.getType();
//		反射实例化对象==BookAction bookaction=new BookAction();
		Action action;
		try {
			action = (Action) Class.forName(type).newInstance();
			if (action instanceof ModelDriver) {//判断子控制器是否实现模型驱动接口
				ModelDriver md=(ModelDriver) action;
//				获取对应实体对象
				Object model = md.getModel();
				Map<String, String[]> map = request.getParameterMap();
//				对应的对象的属性赋值
				BeanUtils.populate(model, map);
			}
			// 调用识别方法类的方法
//			具体业务代码执行后的返回值add/del/upd/list的返回值==》list/tolist
			String res = action.execute(request, response);
//			通过返回值拿到,该方法结果是重定向还是转发那个页面
			ForwardModel forwardModel = actionModel.pop(res);
			if (forwardModel!=null) {
				boolean redirect = forwardModel.isRedirect();
				System.out.println(redirect);
				String path=forwardModel.getPath();
				if (redirect) {
					//重定向
                    response.sendRedirect(request.getContextPath()+"/"+path);
//					response.sendRedirect(path);
				}else {
					//转发
request.getRequestDispatcher(path).forward(request, response);
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
}

3.5 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>
<p>自定义MVCk框架02  最终</p>
<a href="book.do?methodname=add&bid=1&bname=junyi&price=9.9">书籍新增</a>
<a href="book.do?methodname=del">书籍删除</a>
<a href="book.do?methodname=upd">书籍修改</a>
<a href="book.do?methodname=list">书籍查看</a>
</body>
</html>

3.6 项目文件架构

在这里插入图片描述

3.7 测试优化jsp页面参数传递后台的代码

当我们点击书籍新增时将参数传入后台

在这里插入图片描述

结束语

这期博客分享J2EE之自定义MVC框架知识如何去优化上期博客代码就到这里了,如果有老铁想继续学习了解关于J2EE之自定义MVC框架知识请关注我,注意后期博客发表。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

J2EE之自定义MVC框架知识(中篇) 的相关文章

  • 如何在日期选择器中设置不在当前月份的单元格的样式

    我目前正在为我的 JavaFX 应用程序制作注册表 问题是 当日期选择器中的单元格不在页面的月份上时 我想让该单元格变灰 让我们看看我当前的日期选择器 我的日期选择器 正如您所看到的 我希望下个月的日期 27 日 28 日 30 日以及 1
  • 热重载在docker中运行的java程序

    我开发了一个java程序 应该在docker中运行 然而 我在调试docker中运行的java程序时遇到了很多痛苦 我在网上搜索 一些教程提出了像 spring dev tools 这样的工具 因为我的java程序是基于spring boo
  • 如何在 JFace 的 TableViewer 中创建复选框?

    我创建了一个包含两列的 tableViewer 我想将其中一列设为复选框 为此 我创建了一个 CheckBoxCellEditor 但我不知道为什么它不起作用 名为 tableName 的列显示其值正常 色谱柱规格如下 String COL
  • 如何在一行中将字符串数组转换为双精度数组

    我有一个字符串数组 String guaranteedOutput Arrays copyOf values values length String class 所有字符串值都是数字 数据应转换为Double QuestionJava 中
  • Java程序中的数组奇怪的行为[重复]

    这个问题在这里已经有答案了 我遇到了这个 Java 程序及其以意想不到的方式运行 以下程序计算 int 数组中元素对之间的差异 import java util public class SetTest public static void
  • 如何查找 Android 设备中的所有文件并将它们放入列表中?

    我正在寻求帮助来列出 Android 外部存储设备中的所有文件 我想查找所有文件夹 包括主文件夹的子文件夹 有办法吗 我已经做了一个基本的工作 但我仍然没有得到想要的结果 这不起作用 这是我的代码 File files array file
  • Java8无符号算术

    据广泛报道 Java 8 具有对无符号整数的库支持 然而 似乎没有文章解释如何使用它以及有多少可能 有些函数 例如 Integer CompareUnsigned 很容易找到 并且似乎可以实现人们所期望的功能 但是 我什至无法编写一个简单的
  • OnClick 事件中的 finish() 如何工作?

    我有一个Activity一键退出Activity 通过layout xml我必须设置OnClick事件至cmd exit调用 this finish 效果很好 public void cmd exit View editLayout thi
  • Microsoft Graph 身份验证 - 委派权限

    我可以使用 Microsoft Graph 访问资源无需用户即可访问 https developer microsoft com en us graph docs concepts auth v2 service 但是 此方法不允许我访问需
  • 请求位置更新参数

    这就是 requestLocationUpdates 的样子 我使用它的方式 requestLocationUpdates String provider long minTime float minDistance LocationLis
  • 在具有相同属性名称的不同数据类型上使用 ModelMapper

    我有两节课说Animal AnimalDto我想用ModelMapper将 Entity 转换为 DTO 反之亦然 但是对于具有相似名称的一些属性 这些类应该具有不同的数据类型 我该如何实现这一目标 动物 java public class
  • 如何将文件透明地传输到浏览器?

    受控环境 IE8 IIS 7 ColdFusion 当从 IE 发出指向媒体文件 例如 mp3 mpeg 等 的 GET 请求时 浏览器将启动关联的应用程序 Window Media Player 我猜测 IIS 提供文件的方式允许应用程序
  • 反思 Groovy 脚本中声明的函数

    有没有一种方法可以获取 Groovy 脚本中声明的函数的反射数据 该脚本已通过GroovyShell目的 具体来说 我想枚举脚本中的函数并访问附加到它们的注释 Put this到 Groovy 脚本的最后一行 它将作为脚本的返回值 a la
  • 归并排序中的递归:两次递归调用

    private void mergesort int low int high line 1 if low lt high line 2 int middle low high 2 line 3 mergesort low middle l
  • 使用 AWS Java SDK 为现有 S3 对象设置 Expires 标头

    我正在更新 Amazon S3 存储桶中的现有对象以设置一些元数据 我想设置 HTTPExpires每个对象的标头以更好地处理 HTTP 1 0 客户端 我们正在使用AWS Java SDK http aws amazon com sdkf
  • Windows 上的 Nifi 命令

    在我当前的项目中 我一直在Windows操作系统上使用apache nifi 我已经提取了nifi 0 7 0 bin zip文件输入C 现在 当我跑步时 bin run nifi bat as 管理员我在命令行上看到以下消息 但无法运行
  • 如何配置eclipse以保持这种代码格式?

    以下代码来自 playframework 2 0 的示例 Display the dashboard public static Result index return ok dashboard render Project findInv
  • android Accessibility-service 突然停止触发事件

    我有一个 AccessibilityService 工作正常 但由于开发过程中的某些原因它停止工作 我似乎找不到这个原因 请看一下我的代码并告诉我为什么它不起作用 public class MyServicee extends Access
  • com.jcraft.jsch.JSchException:身份验证失败

    当我从本地磁盘上传文件到远程服务器时 出现这样的异常 com jcraft jsch JSchException Auth fail at org apache tools ant taskdefs optional ssh Scp exe
  • Swagger/Openapi-Annotations:如何使用 $ref 生成 allOf?

    我正在生成 Rest 端点 包括添加OpenAPI Swagger对生成的代码进行注释 虽然它对于基本类型运行得很好 但我在自定义类方面遇到了一些问题 现在我有很多自定义类的重复架构条目 使用 Schema 实现 MyClass class

随机推荐

  • MySQL数据行溢出的深入理解

    一 从常见的报错说起 故事的开头我们先来看一个常见的sql报错信息 相信对于这类报错大家一定遇到过很多次了 特别对于OMG这种已内容生产为主要工作核心的BG 在内容线的存储中 数据大一定是个绕不开的话题 这里的数据 大 远不止存储空间占用多
  • jenkins搭建自动化部署(Windows)

    官网 https jenkins io 选择相应版本下载 安装后找到安装目录下jenkins war 可以放在tomcat下运行 也可直接运行命令 java jar jenkins war 启动 关闭命令 net start jenkins
  • mysql 5.6压缩安装_mysql5.6zip格式安装过程

    第一步 到官网下载mysql 5 6 44 winx64的压缩包文件格式 第二步 在我的电脑 gt 属性 gt 高级 gt 环境变量 path变量中添加mysql bin文件夹的路径 第三步 配置完环境变量之后先别忙着启动mysql 我们还
  • 08-分布式

    1 分布式中 接口的幂等性的设计 在高并发场景的架构里 幂等性是必须得保证的 比如说提交作业 查询和删除不在 幂等讨论范围 1 建唯一索引id 每次操作 都根据操作和内容生成唯一的id 在执行之前先判断id是否存在 如果不存在 则 执行后续
  • rem的使用方式

    rem是什么 rem是指相对于根元素的字体大小的单位 在日常开发过程中我们通常把根元素 html body 的字体设置为10px 方便于我们计算 此时子元素的1rem就相当于10px rem与em的区别 各自的优缺点 em子元素字体大小的e
  • CVPR 2019 论文大盘点—人体姿态篇

    CV君盘点了CVPR 2019 中有关人体姿态的论文 其中研究 3D人体姿态估计的论文最多 有 11 篇 研究 2D 姿态估计的 7 篇 姿态迁移 2 篇 人体图像生成 1 篇 人体捕捉 2 篇 另外还有2篇创建了新的基准数据集 姿态估计是
  • python云图

    安装相关插件 python3 m pip install jieba wordcloud matplotlib import matplotlib pyplot as plt import jieba from wordcloud impo
  • 【Spring Boot】【前后端分离】后端接口返回结果统一封装

    文章目录 创建 SpringBoot 项目 封装返回结果 实现返回对象的自动封装 处理异常 测试 最近在尝试使用前后端分离的模式写一个简单的个人博客 遇到接口数据返回结构的问题 在网上查了一圈 发现了一个很好用的方法 在复现的过程中也遇到了
  • 算法设计与分析课后总结

    算法设计与分析课后总结 算法设计与分析 第1章 算法设计基础 课后习题 第二章算法分析基础 课后习题 1 考虑下面算法 回答下列问题 算法完成什么功能 算法的基本语句时什么 基本语句执行了多少次 2 分析以下程序段中基本语句的执行次数 要求
  • 100天精通Python(可视化篇)——第92天:Pyecharts绘制炫酷柱状图、条形图实战大全

    文章目录 专栏导读 1 基础柱状图 2 旋转x轴标签 3 旋转坐标轴 4 添加坐标轴名称 5 添加标记点 6 添加标注线 7 添加数据 8 添加自定义背景图 9 堆叠柱状图 10 柱状图与折线图组合 11 三维柱状图 12 水平滑动 鼠标滚
  • 包、模块、函数的关系结构

    三者关系 python中程序的结构是由包 模块 函数 类大致构成 其关系如下 package module function 模块定义与调用 1 python中一个 py文件都可以是一个module module可以有函数 类 代码组成 如
  • 使用python解决中英混合参考文献中et al 和等的问题

    这个代码使用zipfile将docx进行解压 然后操作document xml文件 找到中文中的et al之后替换为 等 然后再压缩为docx import zipfile import re import os import shutil
  • curl服务器文件,curl 向远程服务器传输file文件

    public function upload 获取上传文件信息 文件名称以自己实际上传文件名称为准 fileinfo FILE filename 请求参数 依据商户自己的参数为准 requestParam version requestPa
  • 声网(agora)音视频通话sdk—微信小程序demo

    首先需要注册一个声网账号 注册成功后创建项目 appid是指声网项目的appid 后续会在小程序的配置文件中用到 微信小程序接入视频通话 需要声网给开通小程序的权限 给声网邮箱发送邮件 注明开通微信小程序接入权限 并给发送appid app
  • Python代码扫描:企业级代码代码安全漏洞扫描Bandit

    目录 什么是Bandit 特点 安装 配置 配置Bandit Pycharm配置外置工具 使用实践 命令行参数 检查单个文件 检查整个目录 PyCharm中对单个文件或者项目目录的扫描 一个使用案例 应用场景 总结 参考资料 注意 后续技术
  • js DOM

    DOM Document Object Model HTML 和 XML 文档的编程接口 通过 DOM JavaScript 能够访问和改变 HTML 文档的所有元素 1 查找 通过 id 查找 HTML 元素 div div 2 通过标签
  • Paper and Codes Leaderboard

    目录 介绍 模型入选标准 1 目标检测 Paper and Codes for COCO by 2023 3 31 COCO FPS Models by 2023 02 18 Look at Batch Size 2 图像分类 ImageN
  • 【Backbone: MLP-Mixer】MLP-Mixer: An all-MLP Architecture for Vision

    Abstract CNN和attention based结构很棒 但不是必须的 本文提出MLP Mixer 一种基于多层感知机 MLPs 的框架 包含两种layers 1 channel mixing MLPs 应用在image patch
  • C++(30)——lambda表达式原理及应用

    lambda lambda这个词起源于数学上的 在C 中利用lambda表达式 可以方便的定义和创建匿名函数 lambda可以看做函数对象的升级版 改进了函数对象以下的缺点 使用在泛型算法中的参数传递的过程中 比较性质 自定义操作 优先级队
  • J2EE之自定义MVC框架知识(中篇)

    J2EE之自定义MVC框架知识 中篇 文章目录 J2EE之自定义MVC框架知识 中篇 前言 1 优化中央控制器中的action容器 使其加载变成可配置的 1 1 编写 xml文件 config xml 1 2 导入XML建模相关的类 Act