Mvc进阶(下)

Mvc进阶(下)

  • 1.前言
  • 2.上次代码弊端
    • 1.利用xml建模反射优化
      • 1.XMl文件
      • 2.对xml建模
    • 3.修改中央控制器
  • 3.再优化
    • 1.先优化Action子控制器
    • 4.优化传值问题
  • 4.总结

在这里插入图片描述

1.前言

虽然前面文章深入解析Java自定义MVC框架的原理与实现讲述了Mvc框架,但是那只能算是比较低级的,还能够再优化,接下来我会再优化3次代码,让代码更为简洁,通用。

2.上次代码弊端

虽然简化了代码,但是代码并不 能够通用,MVC这种东西,最终是要打包成jar架包的,可是上一篇文章的代码优化并不能够打包成架包,现在开始第一次优化。

1.利用xml建模反射优化

1.XMl文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE config
[<!ELEMENT config (action*)><!ELEMENT action (forward*)>
<!ATTLIST action 
path CDATA #REQUIREDtype CDATA #IMPLIED
>]
><!--config标签:可以包含0~N个action标签--><config><!--action标签:可以饱含0~N个forward标签 path:以/开头的字符串,并且值必须唯一 非空 ,子控制器对应的路径type:字符串,非空,子控制器的完整类名--><action path="/book" type="com.niyin.com.BookAction"><forward name="list" path="/res.jsp" redirect="true" /><forward name="tolist" path="/res.jsp" redirect="false" /></action><action path="/order" type="com.niyin.com.Orderaction"><forward name="success" path="/index.jsp" redirect="true" /><forward name="failed" path="/register.jsp" redirect="false" /></action><action path="/bookAction" type="test.BookAction"><forward name="add" path="/bookAdd.jsp" redirect="true" /><forward name="del" path="/reg.jsp" redirect="false" /><forward name="list" path="/list.jsp" redirect="false" /><forward name="upd" path="/login.jsp" redirect="false" /></action><action path="/loginAction" type="test.action.LoginAction"><forward name="a" path="/index.jsp" redirect="false" /><forward name="b" path="/welcome.jsp" redirect="true" /></action>
</config>

2.对xml建模

package model;import java.util.HashMap;
import java.util.Map;public class ActionModel {private String path;private String type;private Map<String ,ForwardModel>fmp=new HashMap<String ,ForwardModel>();public String getType() {return type;}public void setType(String type) {this.type = type;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public void push(ForwardModel forwardModel) {fmp.put(forwardModel.getName(), forwardModel);}public  ForwardModel pop(String name) {return fmp.get(name);}}
package model;import java.util.HashMap;
import java.util.Map;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 =new ConfigMOdelFactory().build();ActionModel actionModel=configModel.pop("/loginAction");ForwardModel forwardModel =actionModel.pop("b");System.out.println(forwardModel.getPath());
}}
package 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;public class ConfigMOdelFactory {public static ConfigModel build() throws Exception {ConfigModel configModel = new ConfigModel();InputStream in = ConfigMOdelFactory.class.getResourceAsStream("/config.xml");SAXReader sr = new SAXReader();Document doc = sr.read(in);List<Element> actionsEles = doc.selectNodes("/config/action");for (Element element : actionsEles) {// System.out.println(element.asXML());ActionModel actionmodel = new ActionModel();actionmodel.setPath(element.attributeValue("path"));actionmodel.setType(element.attributeValue("type"));List<Element> forwardEles = element.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"));forwardModel.setRedirect(!"false".equals(forwardEle.attributeValue("redirect")));actionmodel.push(forwardModel);}configModel.push(actionmodel);}return configModel;}public static void main(String[] args) throws Exception {ConfigMOdelFactory.build();}
}
package model;import java.util.HashMap;
import java.util.Map;public class ForwardModel {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;}}

3.修改中央控制器

以前把所有的子控制器放到map集合中,现在所有的子控制器再config。xml中。

package com.niyin.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.niyin.com.BookAction;
import com.niyin.com.Orderaction;import model.ActionModel;
import model.ConfigMOdelFactory;
import model.ConfigModel;
import model.ForwardModel;@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {private ConfigModel configMOdel;
//	public Map<String, Action> actionMap=new HashMap<String, Action>();@Overridepublic void init() throws ServletException {
//	actionMap.put("/book", new BookAction());
//	actionMap.put("/order", new Orderaction());
//	actionMap.put("/cat", new CatAction());try {configMOdel=ConfigMOdelFactory.build();} catch (Exception e) {// TODO Auto-generated catch blocke.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/再configMOdel中找ActionModel actionModel = configMOdel.pop(uri);if (actionModel==null)throw new RuntimeException("action 没有配置");String type = actionModel.getType();Action action;try {action = (Action) Class.forName(type).newInstance();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }}

把map集合取消,改为用模型的方式来代替map集合,如果要新增类的话只需要新增模型对象即可,不用再加入map集合中,让代码更易于维护和修改,也可以封装架包提供了可行性。

代码测试


<%@ 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>版本1</p>
<a href="Bookservletadd">增加</a>
<a href="Bookservletupd">修改</a>
<a href="Bookservletdel">减少</a>
<a href="Bookservletlist">查询</a><p>版本2</p>
<a href="Bookservletadd?methodName=add">增加</a>
<a href="Bookservletupd?methodName=upd">修改</a>
<a href="Bookservletdel?methodName=del">减少</a>
<a href="Bookservletlist?methodName=list">查询</a>
<p>版本3</p>
<a href="Bookservletadd?methodName=add">增加</a>
<a href="Bookservletupd?methodName=upd">修改</a>
<a href="Bookservletdel?methodName=del">减少</a>
<a href="Bookservletlist?methodName=list">查询</a>
<p>版本4</p>
<a href="book.action?methodName=add">增加</a>
<a href="book.action?methodName=upd">修改</a>
<a href="book.action?methodName=del">减少</a>
<a href="book.action?methodName=list">查询</a>版本4的弊端:中央控制器的action容器加载,不可以灵活配置<p>版本五</p>
<a href="order.action?methodName=add">增加</a>
<a href="order.action?methodName=upd">修改</a>
<a href="order.action?methodName=del">减少</a>
<a href="order.action?methodName=list">查询</a>
</body>
</html>

在这里插入图片描述
控制台输出
在这里插入图片描述

3.再优化

虽然上面代码优化后可以灵活配置了,但是使用重定向和转发有问题,查询必然转发,增删改使用重定向,如果频繁刷新页面,可能会出现重复提交数据。

1.先优化Action子控制器

package com.niyin.framework;import java.io.IOException;
import java.lang.reflect.Method;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class Action {protected String excute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String methoed = request.getParameter("methodName");
//	privateString res="";try {Method m = this.getClass().getDeclaredMethod(methoed, HttpServletRequest.class,HttpServletResponse.class);m.setAccessible(true);res=(String) m.invoke(this, request,response);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return res;}	
}

把book里面的类型也改为String,并返回tolist,和list,通过返回值来判断它是需要重定向还是转发,并且还节约了代码。

package com.niyin.com;import java.io.IOException;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.niyin.entity.Book;
import com.niyin.framework.Action;
import com.niyin.framework.ModelDrivern;public class BookAction extends Action implements ModelDrivern<Book> {
private Book book=new Book();private String list(HttpServletRequest request, HttpServletResponse response) throws Exception {// TODO Auto-generated method stubSystem.out.println("list");
//		response.sendRedirect("res.jsp");request.setAttribute("content", "你就会");
//		request.getRequestDispatcher("res.jsp").forward(request, response);return "list";}private String del(HttpServletRequest request, HttpServletResponse response) throws Exception {// TODO Auto-generated method stubSystem.out.println("del");
//	response.sendRedirect("res.jsp");request.setAttribute("content", "你就会");return "tolist";}private String upd(HttpServletRequest request, HttpServletResponse response) throws Exception {// TODO Auto-generated method stubSystem.out.println("upd");
//	response.sendRedirect("res.jsp");request.setAttribute("content", "你就会");return "tolist";}private String add(HttpServletRequest request, HttpServletResponse response) throws IOException {// TODO Auto-generated method stubSystem.out.println("add");
//	response.sendRedirect("res.jsp");request.setAttribute("content", "你就会");return "tolist";}
@Override
public Book getModel() {System.out.println(book);return book;
}}

优化中央控制器,通过模型对象获取·forward对象来判断该重定向还是转发。

package com.niyin.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.niyin.com.BookAction;
import com.niyin.com.Orderaction;import model.ActionModel;
import model.ConfigMOdelFactory;
import model.ConfigModel;
import model.ForwardModel;@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {private ConfigModel configMOdel;
//	public Map<String, Action> actionMap=new HashMap<String, Action>();@Overridepublic void init() throws ServletException {
//	actionMap.put("/book", new BookAction());
//	actionMap.put("/order", new Orderaction());
//	actionMap.put("/cat", new CatAction());try {configMOdel=ConfigMOdelFactory.build();} catch (Exception e) {// TODO Auto-generated catch blocke.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/再configMOdel中找ActionModel actionModel = configMOdel.pop(uri);String res= action.excute(request, response);ForwardModel forwardModel = actionModel.pop(res);if (forwardModel!=null) {boolean redirect = forwardModel.isRedirect();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 blocke.printStackTrace();} }}

运行结果
在这里插入图片描述
结果是一样的说明优化成功。

4.优化传值问题

一般来说通过servlet拿到前端的值再把它传入数据库,这个过程要写很多重复代码,现在来优化一下,利用反射等等
1.先定义一个模型驱动接口

package com.niyin.framework;/*** * @author 匿瘾** @param <T>* 模型驱动接口*/
public interface ModelDrivern<T> {
T getModel();}

2.让bookaction实现这个接口

package com.niyin.com;import java.io.IOException;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.niyin.entity.Book;
import com.niyin.framework.Action;
import com.niyin.framework.ModelDrivern;public class BookAction extends Action implements ModelDrivern<Book> {
private Book book=new Book();private String list(HttpServletRequest request, HttpServletResponse response) throws Exception {// TODO Auto-generated method stubSystem.out.println("list");
//		response.sendRedirect("res.jsp");request.setAttribute("content", "你就会");
//		request.getRequestDispatcher("res.jsp").forward(request, response);return "list";}private String del(HttpServletRequest request, HttpServletResponse response) throws Exception {// TODO Auto-generated method stubSystem.out.println("del");
//	response.sendRedirect("res.jsp");request.setAttribute("content", "你就会");return "tolist";}private String upd(HttpServletRequest request, HttpServletResponse response) throws Exception {// TODO Auto-generated method stubSystem.out.println("upd");
//	response.sendRedirect("res.jsp");request.setAttribute("content", "你就会");return "tolist";}private String add(HttpServletRequest request, HttpServletResponse response) throws IOException {// TODO Auto-generated method stubSystem.out.println("add");
//	response.sendRedirect("res.jsp");request.setAttribute("content", "你就会");return "tolist";}
@Override
public Book getModel() {System.out.println(book);return book;
}}

3.优化中央控制器

在控制器内判断有没有实现接口,如果实现了就把值传进去。

package com.niyin.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.niyin.com.BookAction;
import com.niyin.com.Orderaction;import model.ActionModel;
import model.ConfigMOdelFactory;
import model.ConfigModel;
import model.ForwardModel;@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {private ConfigModel configMOdel;
//	public Map<String, Action> actionMap=new HashMap<String, Action>();@Overridepublic void init() throws ServletException {
//	actionMap.put("/book", new BookAction());
//	actionMap.put("/order", new Orderaction());
//	actionMap.put("/cat", new CatAction());try {configMOdel=ConfigMOdelFactory.build();} catch (Exception e) {// TODO Auto-generated catch blocke.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/再configMOdel中找ActionModel actionModel = configMOdel.pop(uri);if (actionModel==null)throw new RuntimeException("action 没有配置");String type = actionModel.getType();Action action;try {action = (Action) Class.forName(type).newInstance();//			bookaction 有没有实现这个接口if (action instanceof ModelDrivern) {ModelDrivern md=(ModelDrivern) action;Object bean = md.getModel();Map<String, String[]> map = request.getParameterMap();BeanUtils.populate(bean, map);
//				把值封进去}String res= action.excute(request, response);ForwardModel forwardModel = actionModel.pop(res);if (forwardModel!=null) {boolean redirect = forwardModel.isRedirect();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 blocke.printStackTrace();} }}

最后通过degbug查看book里面是否有值判断是否成功的,传入了值。
结果:
在这里插入图片描述
可以看到book里面是有值的,所以最后一个优化也成功了。

4.总结

通过建模xml和反射的方式优化代码,让代码以Mvc框架的形式出现,
MVC框架构思巧妙。让代码更为简洁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/9331.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

联邦聚合(FedAvg、FedProx、SCAFFOLD)

目录 联邦聚合算法对比(FedAvg、FedProx、SCAFFOLD) 解决问题 FedAvg FedProx SCAFFOLD 实验结果 联邦聚合算法对比(FedAvg、FedProx、SCAFFOLD) 论文链接&#xff1a; FedAvg&#xff1a;Communication-Efficient Learning of Deep Networks from Decentralized Data …

高级Android开发人员枯竭,在这个利润丰厚的领域如何蓬勃发展

为什么高级人才供不应求&#xff1f; 技术行业的发展速度非常快&#xff0c;新的技术和工具不断涌现&#xff0c;导致技能需求不断演变。这使得不断更新和学习变得至关重要。行业发展速度超过了教育和培训体系的能力跟进。传统教育往往滞后于最新的技术趋势和实践&#xff0c;…

FreeRTOS学习笔记—任务挂起和恢复

文章目录 一、任务挂起和恢复API函数1.1 vTaskSuspend()函数1.2 vTaskResume()函数1.3 xTaskResumeFromISR()函数 二、任务挂起和恢复2.1 任务1挂起解挂任务22.2 中断中解挂任务1 三、补充内容3.1 FreeRTOS数据类型3.2 中断优先级分组3.3 错误问题 一、任务挂起和恢复API函数 …

深入理解Go语言中的并发编程【27】【Goroutine的使用、定时器、select】

文章目录 Goroutine池worker pool&#xff08;goroutine池&#xff09; 定时器定时器 selectselect多路复用 Goroutine池 worker pool&#xff08;goroutine池&#xff09; 本质上是生产者消费者模型可以有效控制goroutine数量&#xff0c;防止暴涨需求&#xff1a; 计算一个…

瑞吉外卖-Day01

title: 瑞吉外卖-Day01 abbrlink: ‘0’ date: 2023-04-1 18:00:00 瑞吉外卖-Day01 课程内容 软件开发整体介绍 瑞吉外卖项目介绍 开发环境搭建 后台登录功能开发 后台退出功能开发 1. 软件开发整体介绍 作为一名软件开发工程师,我们需要了解在软件开发过程中的开发流…

从小白到大神之路之学习运维第53天--------tomcat-web应用——————供开发的商城框架

第三阶段基础 时 间&#xff1a;2023年7月5日 参加人&#xff1a;全班人员 内 容&#xff1a; Tomcat应用服务 WEB服务 目录 实验环境&#xff1a;&#xff08;四台服务器&#xff09; 安装tomcat服务&#xff1a; NginxTomcat 负载均衡集群部署&#xff1a; 安装ng…

Python 利用深度学习识别空间推理验证码(一)

注意:本文会比较长,因为空间推理验证码本身比较复杂,我会详细的讲解,我是如何一步一步拆分空间推理的思想去实现的,另外,这里只介绍第一种思想来解决空间推理验证码,实际上,解决该验证码的方法也比较多,这第一种,我会讲解的比较简单,通俗易懂。 注意:下面数据集使用…

HttpRunner自动化之请求中带有 headers 的接口和发送POST请求

headers 可通过headers 添加头部信息&#xff0c;如下图 # 发送请求头headers的接口 - config:name: 百度接口用例base_url: https://www.baidu.com- test:name: 发送百度接口的头部信息request:url: /smethod: GETheaders:Accept: text/html,application/xhtmlxml,applicati…

gitHub

gitHub ** 创建一个仓库 git initgit add .git commit -m “first commit”git branch -M maingit remote add origin gitgithub.com:Dylanmenglliao/demo.gitgit push -u origin main ** 已存在仓库&#xff0c;建立关联 7. git remote add origin gitgithub.com:Dylanme…

遥感云大数据在灾害、水体与湿地领域典型案例及GPT模型

详情点击链接&#xff1a;遥感云大数据在灾害、水体与湿地领域典型案例实践及GPT模型 第一&#xff1a;基础 一&#xff1a;平台及基础开发平台 GEE平台及典型应用案例&#xff1b; GEE开发环境及常用数据资源&#xff1b; ChatGPT、文心一言等GPT模型 JavaScript基础&am…

【Hello mysql】 数据库基础

Mysql专栏&#xff1a;Mysql 本篇博客简介&#xff1a;简单的介绍mysql相关的一些基础知识和在Linux环境下的安装 让大家对于mysql有一个初步的认知 数据库基础 数据库基础数据库定义数据库再理解软件角度文件角度总结 主流数据库mysql安装卸载不要的环境获取mysql官方yum源安装…

java中预览pdf或者图片

GetMapping("preview1")ApiOperation(value "根据文件名实现预览功能")public void previewFile1( HttpServletResponse response) throws IOException {String filePath"C:\\Users\\Harbor Lau\\Desktop\\哈哈\\""11月燃油费(公开).pdf&q…