当前位置:网站首页>Custom MVC framework implementation
Custom MVC framework implementation
2022-06-29 09:49:00 【lion tow】
Catalog
One 、 The central controller dynamically loads the storage sub controller
Two 、 Optimization of parameter passing encapsulation
3、 ... and 、 Return value page Jump optimization
Four 、 The framework configuration file is variable
One 、 The central controller dynamically loads the storage sub controller
Last shared to , How do we optimize the creation of different objects to facilitate coding when we want to implement different functions MVC Framework optimization , But it's not convenient enough, so let's continue to optimize :
Question 1 : Each initialization of the central controller shall be manually added

Analyze and solve :
1. adopt XML Modeling we can know , Final configModel The object will contain config.xml Information of all sub controllers in
2. At the same time, in order to solve the problem that the central controller can dynamically load and save the information of sub controllers , So we just need to introduce congigModel Objects can also be initialized
So we need to use our XML Knowledge of modeling :
config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<action path="/book" type="com.zq.Servlet.BookAction">
<forward name="failed" path="/login.jsp" redirect="false" />
<forward name="success" path="/main.jsp" redirect="true" />
</action>
</config>Yes DispatcherServlet To transform :
package com.zq.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;
/**
* The central controller
* Main functions : Accept browser requests , Find the corresponding handler
* @author Zhang Qiang
*
* 2022 year 6 month 25 On the afternoon of Sunday 2:32:46
*/
@WebServlet("*.action")
public class DispatcherServlet extends HttpServlet{
private Map<String, Action> actions = new HashMap<String, Action>();
// Through modeling, we can know the final ConfigModel The object will contain config.xml All self-control information in
private ConfigModel ConfigModel;
// When the program starts, it will be executed once
@Override
public void init() throws ServletException {
// actions.put("/book", new BookAction());
// actions.put("/order", new OrederAction());
try {
ConfigModel= ConfigModelFactory.bulid();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uri = req.getRequestURI();
// To get /book
uri=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
//Action action = actions.gaet(uri);
// Compared with the previous one from map Get sub controllers from the collection , Currently, you need to obtain config.xml The full pathname in , Then reflect instantiation
ActionModel actionModel = ConfigModel.pop(uri);
if(actionModel == null) {
throw new RuntimeException("action To configure error ");
}
String type = actionModel.getType();// The full pathname in the configuration file action Full pathname of the sub controller
try {
Action action = (Action) Class.forName(type).newInstance();//action Example
action.execute(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Page code :Demo01:
<h2> Optimize </h2>
<a href="${pageContext.request.contextPath}/book.action?methodName=add"> increase </a>
<a href="${pageContext.request.contextPath}/book.action?methodName=del"> Delete </a>
<a href="${pageContext.request.contextPath}/book.action?methodName=update"> modify </a>
<a href="${pageContext.request.contextPath}/book.action?methodName=check"> see </a>
<a href="${pageContext.request.contextPath}/book.action?methodName=load"> The echo </a>
By doing this, we can realize that we only need to modify... Without changing any code XML The configuration file can be used to add sub controllers
Two 、 Optimization of parameter passing encapsulation
Question two : We pass too many parameters. Can we not use req.getp Directly get the passed parameters ?
Demo1: We use add For example, we passed three parameters bid、bname、price
<h2> Parameter transfer optimization </h2>
<a href="${pageContext.request.contextPath }/book.action?methodName=add&bid=989898&bname=laoliu&price=89"> increase </a>
<a href="${pageContext.request.contextPath}/book.action?methodName=del"> Delete </a>
<a href="${pageContext.request.contextPath}/book.action?methodName=update"> modify </a>
<a href="${pageContext.request.contextPath}/book.action?methodName=check"> see </a>
<a href="${pageContext.request.contextPath}/book.action?methodName=load"> The echo </a>To build a com.zq.entity My bag Build a... In it Book The entity class
package com.zq.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;
}
@Override
public String toString() {
return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
}
}
Before optimization add Method :
package com.zq.Servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zq.entity.book;
import com.zq.framework.Action;
import com.zq.framework.ActionSupport;
public class BookAction extends ActionSupport {
private void load(HttpServletRequest request, HttpServletResponse response) {
System.out.println(" In the same Servlet in , Call to query a single method ");
}
private void check(HttpServletRequest request, HttpServletResponse response) {
System.out.println(" In the same Servlet in , Call the method of view ");
}
private void update(HttpServletRequest request, HttpServletResponse response) {
System.out.println(" In the same Servlet in , Call the modified method ");
}
private void del(HttpServletRequest request, HttpServletResponse response) {
System.out.println(" In the same Servlet in , Call the deleted method ");
}
private void add(HttpServletRequest request, HttpServletResponse response) {
String bid = request.getParameter("bid");
String bname = request.getParameter("bname");
String price = request.getParameter("price");
book book = new book();
book.setBid(Integer.valueOf(bid));
book.setBname(bname);
book.setPrice(Float.valueOf(price));
System.out.println(" Using a servlet Call in add Method "+book);
}
}
If we pass a lot of values, we need to accept a lot of repeated code, so we optimize it :
Optimize BookAction:
package com.zq.Servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zq.entity.book;
import com.zq.framework.Action;
import com.zq.framework.ActionSupport;
import com.zq.framework.ModelDriven;
public class BookAction extends ActionSupport implements ModelDriven<book>{
private book book = new book();
private void list(HttpServletRequest req, HttpServletResponse resp) {
System.out.println(" Using a servlet Call in list Method ");
}
private void load(HttpServletRequest req, HttpServletResponse resp) {
System.out.println(" Using a servlet Call in list Method ");
}
private void edit(HttpServletRequest req, HttpServletResponse resp) {
System.out.println(" Using a servlet Call in edit Method ");
}
private void del(HttpServletRequest req, HttpServletResponse resp) {
System.out.println(" Using a servlet Call in del Method ");
}
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(" Using a servlet Call in add Method "+book);
}
@Override
public book getModel() {
return book;
}
}
Create an interface ModelDriven:
package com.zq.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;
}
@Override
public String toString() {
return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
}
}
reform DispatcherServlet:
package com.zq.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;
/**
* The central controller
* Main functions : Accept browser requests , Find the corresponding handler
* @author Zhang Qiang
*
* 2022 year 6 month 25 On the afternoon of Sunday 2:32:46
*/
@WebServlet("*.action")
public class DispatcherServlet extends HttpServlet{
private Map<String, Action> actions = new HashMap<String, Action>();
// Through modeling, we can know the final ConfigModel The object will contain config.xml All self-control information in
private ConfigModel ConfigModel;
// When the program starts, it will be executed once
@Override
public void init() throws ServletException {
// actions.put("/book", new BookAction());
// actions.put("/order", new OrederAction());
try {
ConfigModel= ConfigModelFactory.bulid();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uri = req.getRequestURI();
// To get /book
uri=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
//Action action = actions.gaet(uri);
// Compared with the previous one from map Get sub controllers from the collection , Currently, you need to obtain config.xml The full pathname in , Then reflect instantiation
ActionModel actionModel = ConfigModel.pop(uri);
if(actionModel == null) {
throw new RuntimeException("action To configure error ");
}
String type = actionModel.getType();// The full pathname in the configuration file action Full pathname of the sub controller
try {
Action action = (Action) Class.forName(type).newInstance();//action Example
if(action instanceof ModelDriven) {
// So it can be transformed downward
ModelDriven md = (ModelDriven)action;
//model refer to bookAction Medium book Class instance
Object model = md.getModel();
// to model Property assignment in , To accept the front end jsp Parameters passed req.getParameterMap()
//PropertyUtils.getIndexedProperty(bean, name) Take a value from an object
// Encapsulate all front-end parameter values into entity classes
BeanUtils.populate(model, req.getParameterMap());
}
action.execute(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、 ... and 、 Return value page Jump optimization
Question 3 : After we implement the function, we will need to jump to the page. But can we not add duplicate code but realize the jump function ?
The solution is to put our jump path in the same way XML In profile
Reform the sub controller :
package com.zq.framework;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Sub controller
* The corresponding handler
* @author Zhang Qiang
*
* 2022 year 6 month 25 On the afternoon of Sunday 2:34:21
*/
public interface Action {
String execute(HttpServletRequest request, HttpServletResponse response);
}
ForwardModel:
package com.zq.framework;
/**
* Corresponding forward label
* @author yang
*
* @date 2022 year 6 month 15 The morning of 9:05:38
*/
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 getRedirect() {
return redirect;
}
public void setRedirect(boolean b) {
this.redirect = b;
}
public boolean isRedirect() {
return redirect;
}
}
ActionSupport:
package com.zq.framework;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ActionSupport implements Action {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) {
String methodName = request.getParameter("methodName");
// methodName May be add/del/edit/list/load/xxx/yyy/aaa...
// What method does the front desk transfer , Call the corresponding method of the current class
try {
Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
m.setAccessible(true);
// Call the... Of the current class instance methodName Method
return (String) m.invoke(this, request,response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
DispatcherServlet:
package com.zq.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;
/**
* The central controller
* Main functions : Accept browser requests , Find the corresponding handler
* @author Zhang Qiang
*
* 2022 year 6 month 25 On the afternoon of Sunday 2:32:46
*/
@WebServlet("*.action")
public class DispatcherServlet extends HttpServlet{
private Map<String, Action> actions = new HashMap<String, Action>();
// Through modeling, we can know the final ConfigModel The object will contain config.xml All self-control information in
private ConfigModel ConfigModel;
// When the program starts, it will be executed once
@Override
public void init() throws ServletException {
// actions.put("/book", new BookAction());
// actions.put("/order", new OrederAction());
try {
ConfigModel= ConfigModelFactory.bulid();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uri = req.getRequestURI();
// To get /book
uri=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
//Action action = actions.gaet(uri);
// Compared with the previous one from map Get sub controllers from the collection , Currently, you need to obtain config.xml The full pathname in , Then reflect instantiation
ActionModel actionModel = ConfigModel.pop(uri);
if(actionModel == null) {
throw new RuntimeException("action To configure error ");
}
String type = actionModel.getType();// The full pathname in the configuration file action Full pathname of the sub controller
try {
Action action = (Action) Class.forName(type).newInstance();//action Example
if(action instanceof ModelDriven) {
// So it can be transformed downward
ModelDriven md = (ModelDriven)action;
//model refer to bookAction Medium book Class instance
Object model = md.getModel();
// to model Property assignment in , To accept the front end jsp Parameters passed req.getParameterMap()
//PropertyUtils.getIndexedProperty(bean, name) Take a value from an object
// Encapsulate all front-end parameter values into entity classes
BeanUtils.populate(model, req.getParameterMap());
// Before formally calling this method book The attributes in the are assigned
String result = action.execute(req,resp);
ForwardModel forwardModel = actionModel.pop(result);
// if(forwardModel == null)
// throw new RuntimeException("forward config error");
// /bookList.jsp /index.jsp
String path = forwardModel.getPath();
// Get the configuration to be forwarded
boolean redirect = forwardModel.isRedirect();
if(redirect)
resp.sendRedirect(path);
else
req.getRequestDispatcher(path).forward(req, resp);
}
action.execute(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
But if we test now to see if we can jump to the interface, there should be a case that the path loses the project name

The solution is to modify again DispatcherServlet:
// Get the configuration to be forwarded
boolean redirect = forwardModel.isRedirect();
if(redirect)
resp.sendRedirect(req.getServletContext().getContextPath()+path);
else
req.getRequestDispatcher(path).forward(req, resp);
Four 、 The framework configuration file is variable
Question 4 : If we change XML What about the file name of the configuration file ?
Revise it DispatcherServlet:
package com.zq.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;
/**
* The central controller
* Main functions : Accept browser requests , Find the corresponding handler
* @author Zhang Qiang
*
* 2022 year 6 month 25 On the afternoon of Sunday 2:32:46
*/
@WebServlet("*.action")
public class DispatcherServlet extends HttpServlet{
private Map<String, Action> actions = new HashMap<String, Action>();
// Through modeling, we can know the final ConfigModel The object will contain config.xml All self-control information in
private ConfigModel ConfigModel;
// When the program starts, it will be executed once
@Override
public void init() throws ServletException {
// actions.put("/book", new BookAction());
// actions.put("/order", new OrederAction());
try {
// Configure address
//getInitParameter The function of is to get web.xml Medium servlet Information configuration parameters
String configLocation = this.getInitParameter("configLocation");
if(configLocation == null || "".equals(configLocation))
ConfigModel = ConfigModelFactory.bulid();
else
ConfigModel = ConfigModelFactory.bulid(configLocation);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uri = req.getRequestURI();
// To get /book
uri=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
//Action action = actions.gaet(uri);
// Compared with the previous one from map Get sub controllers from the collection , Currently, you need to obtain config.xml The full pathname in , Then reflect instantiation
ActionModel actionModel = ConfigModel.pop(uri);
if(actionModel == null) {
throw new RuntimeException("action To configure error ");
}
String type = actionModel.getType();// The full pathname in the configuration file action Full pathname of the sub controller
try {
Action action = (Action) Class.forName(type).newInstance();//action Example
if(action instanceof ModelDriven) {
// So it can be transformed downward
ModelDriven md = (ModelDriven)action;
//model refer to bookAction Medium book Class instance
Object model = md.getModel();
// to model Property assignment in , To accept the front end jsp Parameters passed req.getParameterMap()
//PropertyUtils.getIndexedProperty(bean, name) Take a value from an object
// Encapsulate all front-end parameter values into entity classes
BeanUtils.populate(model, req.getParameterMap());
// Before formally calling this method book The attributes in the are assigned
String result = action.execute(req,resp);
ForwardModel forwardModel = actionModel.pop(result);
// if(forwardModel == null)
// throw new RuntimeException("forward config error");
// /bookList.jsp /index.jsp
String path = forwardModel.getPath();
// Get the configuration to be forwarded
boolean redirect = forwardModel.isRedirect();
if(redirect)
resp.sendRedirect(path);
else
req.getRequestDispatcher(path).forward(req, resp);
}
action.execute(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>t280_mvc</display-name>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>com.cdl.framework.DispatcherServlet</servlet-class>
<init-param>
<param-name>configLaction</param-name>
<param-value>/wuyanzu2</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>take config.xml->wuyanzu2.xml
In this case, even if we modify the name of the configuration file ourselves, there will be no problem
边栏推荐
- UE4 blueprint modify get a copy in array to reference
- Matlab tips (21) matrix analysis -- partial least squares regression
- programing language
- Pytorch Summary - Automatic gradient
- UE4 动画重定向
- Western Polytechnic University, one of the "seven national defense schools", was attacked by overseas networks
- UE4 compile a single file (VS and editor start respectively)
- Hb5470 combustion test of non-metallic materials in civil aircraft cabin
- Es error nonodeavailableexception[none of the configured nodes are available:[.127.0.0.1}{127.0.0.1:9300]
- 爱快安装或重置后,PC或手机端获取不到ip
猜你喜欢

Data governance: data standard management (Part III)

基于stm32标准库独立按键的多按键状态机的实现

商业智能BI的未来,如何看待AI+BI这种模式?

转载 :判断对象是否具有属性的5种方法

Western Polytechnic University, one of the "seven national defense schools", was attacked by overseas networks

自定义mvc框架实现

Matlab tips (21) matrix analysis -- partial least squares regression

五心公益红红娘团队

Factory mode

UE4 remove the mask transparent white edge in the material
随机推荐
基于keil5自动配置stm32f103标准库的官网freertos移植
Data governance: the solution of data governance in the data Arena
数据可视化:数据可视化的意义
微信小程序实现store功能
Segmentation of Head and Neck Tumours Using Modified U-net
五心公益红红娘团队
《网络是怎么样连接的》读书笔记 - WEB服务端请求和响应(五)
Understanding of singleton mode
The 23 most useful elasticsearch search techniques you must know
Pytorch summary learning series - broadcast mechanism
Idea debugging fails, reporting jdwp no transports initialized, jvmtierror=agent_ ERROR_ TRANSPORT_ LOAD(196)
UE4 blueprint modify get a copy in array to reference
Official STM32 chip package download address stm32f10x stm32f40x Download
数据处理时代,数据质量建设才是企业的生存之道
Introduction to Chang'an chain data storage and construction of MySQL storage environment
Uber 前安全主管面临欺诈指控,曾隐瞒数据泄露事件
Fabrication d'une calculatrice d'addition simple basée sur pyqt5 et Qt Designer
Research progress of target detection in the era of deep convolutional neural network
IDEA自动补全
InvalidConnectionAttributeException异常处理