当前位置:网站首页>简单自定义MVC优化
简单自定义MVC优化
2022-06-30 02:58:00 【安离九歌】
前言
这篇文章接上一篇文章,上一篇文章分享了简单的自定义了MVC。本片文章就来分享自定义MVC优化。
一、中央控制器动态加载储存子控制器
我们自定义MVC最后要将它导出成jar包,那如果我们要加的子控制器怎么办,都导成jar包。
这里我们就要用到之前分享的内容XML。
通过之前的建模我们可以知道,configModel对象会包含config.xml中的所有子控制器信息
同时为了解决中央控制器能够动态的加载保存子控制器的信息,我们只需要引入configModel对象即可
DispatcherServlet
package com.zhw.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 com.zhw.web.BookAction;
import com.zhw.xml.ActionModel;
import com.zhw.xml.ConfigModel;
import com.zhw.xml.ConfigModelFactory;
//@WebServlet("*.action")
public class DispatcherServlet extends HttpServlet{
// private Map<String,Action> actions = new HashMap<String,Action>();
private ConfigModel configModel;
/*
* 通过之前的建模我们可以知道,configModel对象会包含config.xml中的所有子控制器信息
* 同时为了解决中央控制器能够动态的加载保存子控制器的信息,我们只需要引入configModel对象即可
*/
@Override
public void init() throws ServletException {
// actions.put("/book",new BookAction());
// actions.put("/order",new BookAction());
try {
configModel = ConfigModelFactory.bulid();
} 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/mvc/book.action?methodName=list
String uri = req.getRequestURI();
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
// Action action = actions.get(uri);
// action.execute(req, resp);
//
ActionModel actionModel = configModel.pop(uri);
if(actionModel == null) {
throw new RuntimeException("action 配置错误 ");
}
//是action子控制器的全路径名
String type = actionModel.getType();
try {
//类类是反射的开始,通过子控制器的全路径名用newInstance方法得到子控制器。
Action action = (Action) Class.forName(type).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
}
config.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<action path="/book" type="com.zhw.web.BookAction">
<forward name="failed" path="/login.jsp" redirect="false" />
<forward name="success" path="/main.jsp" redirect="true" />
</action>
</config>ConfigModel
package com.zhw.xml;
import java.util.HashMap;
import java.util.Map;
/**
* 对应标签
* @author zhw
*
*/
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);
}
}
ConfigModelFactory
package com.zhw.xml;
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种设计模式之工厂模式
* sessionfactory
*
* @author zhw
*
*/
public class ConfigModelFactory {
public static ConfigModel bulid() throws Exception {
String defaultPath = "/config.xml";
InputStream in = ConfigModelFactory.class.getResourceAsStream(defaultPath);
SAXReader s = new SAXReader();
Document doc = s.read(in);
ConfigModel configModel = new ConfigModel();
List<Element> actionEles = doc.selectNodes("/config/action");
for (Element ele : actionEles) {
ActionModel actionModel = new ActionModel();
actionModel.setPath(ele.attributeValue("path"));
actionModel.setType(ele.attributeValue("type"));
//将forwardModel 赋值并添加到ActionModel
List<Element> forwardEles = ele.selectNodes("forward");
for (Element fele : forwardEles) {
ForwardModel forwardModel = new ForwardModel();
forwardModel.setName(fele.attributeValue("name"));
forwardModel.setPath(fele.attributeValue("path"));
forwardModel.setRedirect("true".equals(fele.attributeValue("redirect")));
actionModel.push(forwardModel);
}
configModel.push(actionModel);
}
return configModel;
}
}
优化后运行:


二、参数传递封装
假设我们需要新增一本书籍,需要传的为书籍编号,书籍名称,书籍价格。三个参数,很方便,但是如果需要传三十个参数呢?为了这个问题,对参数传递封装
未优化前:
Demo
<%@ 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>
<h3>目前增删改查的方法</h3>
<a href="${pageContext.request.contextPath }/book/add">增加</a>
<a href="${pageContext.request.contextPath }/book/del">删除</a>
<a href="${pageContext.request.contextPath }/book/edit">修改</a>
<a href="${pageContext.request.contextPath }/book/list">查询</a>
<!-- r
上述问题:
1、关于单个实体/表操作场景越多,需要新建的类也就越多,造成了项目中类的数量过于庞大
2、当新增了业务,除了要添加该业务对应的方法(load),同时还要改动原有的方法
3、反射相关代码、在每一个实体类对应的Servlet中都存在
4、每一个Servlets中都有doget、dopost
-->
<h3>类数量过多问题的优化</h3>
<a href="${pageContext.request.contextPath }/book.action?methodName=add">增加</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=edit">修改</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>
<h3>订单类CRUD</h3>
<a href="${pageContext.request.contextPath }/order.action?methodName=add">增加</a>
<a href="${pageContext.request.contextPath }/order.action?methodName=del">删除</a>
<a href="${pageContext.request.contextPath }/order.action?methodName=edit">修改</a>
<a href="${pageContext.request.contextPath }/order.action?methodName=list">查询</a>
<a href="${pageContext.request.contextPath }/order.action?methodName=load">回显</a>
<h3>xx</h3>
<a href="${pageContext.request.contextPath }/book.action?methodName=add&bid=123&bname=logo&price=99">增加</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=edit">修改</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>
</body>
</html>BookAction
package com.zhw.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zhw.entity.Book;
import com.zhw.framework.ActionSupport;
public class BookAction extends ActionSupport{
private void list(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("在同样一个Servlet中调用list方法");
}
private void edit(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("在同样一个Servlet中调用edit方法");
}
private void del(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("在同样一个Servlet中调用del方法");
}
private void add(HttpServletRequest req, HttpServletResponse resp) {
String bid = req.getParameter("bid");
String bname = req.getParameter("bname");
String price = req.getParameter("price");
Book book = new Book();
book.setBid(Integer.valueOf(bid));
book.setBname(bname);
book.setPrice(Float.valueOf(price));
System.out.println("在同样一个Servlet中调用add方法");
}
private void load(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("在同样一个Servlet中调用load方法");
}
}
Book
package com.zhw.entity;
public class Book {
private int bid;
private String bname;
private float price;
public int getBid() {
return bid;
}
public void setBid(int bid) {
this.bid = bid;
}
public String getBname() {
return bname;
}
public void setBname(String bname) {
this.bname = bname;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public Book() {
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
}
}
优化后:
DispatcherServlet
package com.zhw.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.zhw.web.BookAction;
import com.zhw.xml.ActionModel;
import com.zhw.xml.ConfigModel;
import com.zhw.xml.ConfigModelFactory;
import com.zhw.xml.ForwardModel;
//@WebServlet("*.action")
public class DispatcherServlet extends HttpServlet{
// private Map<String,Action> actions = new HashMap<String,Action>();
private ConfigModel configModel;
/*
* 通过之前的建模我们可以知道,configModel对象会包含config.xml中的所有子控制器信息
* 同时为了解决中央控制器能够动态的加载保存子控制器的信息,我们只需要引入configModel对象即可
*/
@Override
public void init() throws ServletException {
// actions.put("/book",new BookAction());
// actions.put("/order",new BookAction());
try {
String configLocation = this.getInitParameter("configLocation");
if(configLocation == null ||"".equals(configLocation)) {
}
configModel = ConfigModelFactory.bulid();
} 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/mvc/book.action?methodName=list
String uri = req.getRequestURI();
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
// Action action = actions.get(uri);
// action.execute(req, resp);
//
ActionModel actionModel = configModel.pop(uri);
if(actionModel == null) {
throw new RuntimeException("action 配置错误 ");
}
//是action子控制器的全路径名
String type = actionModel.getType();
try {
//类类是反射的开始,通过子控制器的全路径名用newInstance方法得到子控制器。
Action action = (Action) Class.forName(type).newInstance();
if(action instanceof ModelDriven) {
ModelDriven md = (ModelDriven)action;
Object model = md.getModel();
//将前端所有参数值封装进实体类
BeanUtils.populate(model, req.getParameterMap());
}
// 正式调用放法,book中的属性要被赋值
// action.execute(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Demo
<%@ 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>
<h3>参数传递封装的优化</h3>
<a href="${pageContext.request.contextPath }/book.action?methodName=add&bid=989898&bname=laoliu&price=89">增加</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=edit">修改</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
<a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>
</body>
</html>BookAction
package com.zhw.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zhw.entity.Book;
import com.zhw.framework.ActionSupport;
import com.zhw.framework.ModelDriven;
public class BookAction extends ActionSupport implements ModelDriven<Book>{
private Book book = new Book();
private String list(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("在同样一个Servlet中调用list方法");
return "success";
}
private void edit(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("在同样一个Servlet中调用edit方法");
}
private void del(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("在同样一个Servlet中调用del方法");
}
private String add(HttpServletRequest req, HttpServletResponse resp) {
// String bid = req.getParameter("bid");
// String bname = req.getParameter("bname");
// String price = req.getParameter("price");
// Book book = new Book();
// book.setBid(Integer.valueOf(bid));
// book.setBname(bname);
// book.setPrice(Float.valueOf(price));
System.out.println("在同样一个Servlet中调用add方法");
return "failed";
}
private void load(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("在同样一个Servlet中调用load方法");
}
@Override
public Book getModel() {
return book;
}
}
三、方法执行结果优化
对方法的执行结果进行优化,如果增加成功就用转发,失败就用重定向。
DispatcherServlet
package com.zhw.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.zhw.web.BookAction;
import com.zhw.xml.ActionModel;
import com.zhw.xml.ConfigModel;
import com.zhw.xml.ConfigModelFactory;
import com.zhw.xml.ForwardModel;
//@WebServlet("*.action")
public class DispatcherServlet extends HttpServlet{
// private Map<String,Action> actions = new HashMap<String,Action>();
private ConfigModel configModel;
/*
* 通过之前的建模我们可以知道,configModel对象会包含config.xml中的所有子控制器信息
* 同时为了解决中央控制器能够动态的加载保存子控制器的信息,我们只需要引入configModel对象即可
*/
@Override
public void init() throws ServletException {
// actions.put("/book",new BookAction());
// actions.put("/order",new BookAction());
try {
String configLocation = this.getInitParameter("configLocation");
if(configLocation == null ||"".equals(configLocation)) {
}
configModel = ConfigModelFactory.bulid();
} 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/mvc/book.action?methodName=list
String uri = req.getRequestURI();
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
// Action action = actions.get(uri);
// action.execute(req, resp);
//
ActionModel actionModel = configModel.pop(uri);
if(actionModel == null) {
throw new RuntimeException("action 配置错误 ");
}
//是action子控制器的全路径名
String type = actionModel.getType();
try {
//类类是反射的开始,通过子控制器的全路径名用newInstance方法得到子控制器。
Action action = (Action) Class.forName(type).newInstance();
if(action instanceof ModelDriven) {
ModelDriven md = (ModelDriven)action;
Object model = md.getModel();
//将前端所有参数值封装进实体类
BeanUtils.populate(model, req.getParameterMap());
}
// 正式调用放法,book中的属性要被赋值
action.execute(req, resp);
String result = action.execute(req, resp);
ForwardModel forwardModel = actionModel.pop(result);
boolean redirect = forwardModel.isRedirect();
if(forwardModel == null) {
throw new RuntimeException("forward config error");
}
String path = forwardModel.getPath();
if(redirect)
resp.sendRedirect(req.getServletContext().getContextPath()+path);
else
req.getRequestDispatcher(path).forward(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<action path="/book" type="com.zhw.web.BookAction">
<forward name="success" path="/Demo2.jsp" redirect="false" />
<forward name="failed" path="/Demo3.jsp" redirect="true" />
</action>
</config>forwardModel
package com.zhw.xml;
/**
* @author zhw
*
*/
public class ForwardModel {
// <forward name="failed" path="/reg.jsp" redirect="false" />
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 getRedirect() {
return redirect;
}
public void setRedirect(Boolean redirect) {
this.redirect = redirect;
}
public boolean isRedirect() {
return redirect;
}
}


四、框架配置文件可变
DispatcherServlet
package com.zhw.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.zhw.web.BookAction;
import com.zhw.xml.ActionModel;
import com.zhw.xml.ConfigModel;
import com.zhw.xml.ConfigModelFactory;
import com.zhw.xml.ForwardModel;
//@WebServlet("*.action")
public class DispatcherServlet extends HttpServlet{
// private Map<String,Action> actions = new HashMap<String,Action>();
private ConfigModel configModel;
/*
* 通过之前的建模我们可以知道,configModel对象会包含config.xml中的所有子控制器信息
* 同时为了解决中央控制器能够动态的加载保存子控制器的信息,我们只需要引入configModel对象即可
*/
@Override
public void init() throws ServletException {
// actions.put("/book",new BookAction());
// actions.put("/order",new BookAction());
try {
String configLocation = this.getInitParameter("configLocation");
if(configLocation == null ||"".equals(configLocation)) {
}
configModel = ConfigModelFactory.bulid();
} 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/mvc/book.action?methodName=list
String uri = req.getRequestURI();
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
// Action action = actions.get(uri);
// action.execute(req, resp);
//
ActionModel actionModel = configModel.pop(uri);
if(actionModel == null) {
throw new RuntimeException("action 配置错误 ");
}
//是action子控制器的全路径名
String type = actionModel.getType();
try {
//类类是反射的开始,通过子控制器的全路径名用newInstance方法得到子控制器。
Action action = (Action) Class.forName(type).newInstance();
if(action instanceof ModelDriven) {
ModelDriven md = (ModelDriven)action;
Object model = md.getModel();
//将前端所有参数值封装进实体类
BeanUtils.populate(model, req.getParameterMap());
}
// 正式调用放法,book中的属性要被赋值
action.execute(req, resp);
String result = action.execute(req, resp);
ForwardModel forwardModel = actionModel.pop(result);
boolean redirect = forwardModel.isRedirect();
if(forwardModel == null) {
throw new RuntimeException("forward config error");
}
String path = forwardModel.getPath();
if(redirect)
resp.sendRedirect(req.getServletContext().getContextPath()+path);
else
req.getRequestDispatcher(path).forward(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>ss</display-name>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>com.zhw.framework.DispatcherServlet</servlet-class>
<init-param>
<param-name>configLocation</param-name>
<param-value>laoliu</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>将config.xml改为laoliu.xml
总结
在上一次的简单的自定义mvc后,我们对此进行了优化,优化后减少了代码量,缩短开发时间。
本次的内容分享到这。如有错误,还望指正。
边栏推荐
- Software testing skills, JMeter stress testing tutorial, transaction controller of logic controller (25)
- How to set password complexity and timeout exit function in Oracle
- Visual HTA form designer htamaker interface introduction and usage, Download | HTA VBS visual script writing
- Cmake tutorial series -02- generating binaries using cmake code
- 多卡服务器使用
- 2022 new test questions for safety management personnel of metal and nonmetal mines (small open pit quarries) and certificate examination for safety management personnel of metal and nonmetal mines (s
- What about punctuation in the first column of unity text
- 浅谈IDEA的优化和使用
- High paid programmers & interview questions series 63: talk about the differences between sleep (), yield (), join (), and wait ()
- mysqldump原理
猜你喜欢

Cross domain, CORS, jsonp

约瑟夫环 数学解法

2.8 【 weight of complete binary tree 】

Raki's notes on reading paper: named entity recognition as dependency parsing

oracle怎么设置密码复杂度及超时退出的功能

IBM WebSphere channel connectivity setup and testing

2. successfully solved bug:exception when publishing [Failed to connect and initialize SSH connection...

自定义JvxeTable的按钮及备注下$set的用法

Recursion frog jumping steps problem

Implementation of Sanzi chess with C language
随机推荐
Distributed file storage system fastdfs hands on how to do it
Lua Basics
Pytoch learning (II)
Global and Chinese market for defense network security 2022-2028: Research Report on technology, participants, trends, market size and share
How do I enable assembly binding logging- How can I enable Assembly binding logging?
New edition of diazotization process in 2022 and analysis of diazotization process
Unity3d ugui force refresh of layout components
Recursion frog jumping steps problem
HTA introductory basic tutorial | GUI interface of vbs script HTA concise tutorial, with complete course and interface beautification
Unity timeline data binding
JMeter obtains cookies across thread groups or JMeter thread groups share cookies
Mysql表数据比较大情况下怎么修改添加字段
Cross domain, CORS, jsonp
正则全匹配:密码由8位以上数字,大小写字母,特殊字符组成
Threejs mirror case reflector create mirror + house construction + small ball movement
Some configuration details about servlet initial development
Time complexity analysis
Linear algebra Chapter 3 summary of vector and vector space knowledge points (Jeff's self perception)
Raki's notes on reading paper: Leveraging type descriptions for zero shot named entity recognition and classification
O & M (20) make and start USB flash disk and install win10