当前位置:网站首页>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
边栏推荐
- Fabrication d'une calculatrice d'addition simple basée sur pyqt5 et Qt Designer
- Deep Learning-based Automated Delineation of Head and Neck Malignant Lesions from PET Images
- Factory mode
- Five heart charity matchmaker team
- c#判断数组是否包含另一个数组的任何项
- watch监听和computed计算属性的使用和区别
- UE4 compile a single file (VS and editor start respectively)
- Official STM32 chip package download address stm32f10x stm32f40x Download
- Mh/t 6040 smoke density test of aviation materials
- IDEA调试失败,报JDWP No transports initialized, jvmtiError=AGENT_ERROR_TRANSPORT_LOAD(196)
猜你喜欢

Making of simple addition calculator based on pyqt5 and QT Designer

GD32F4xx 以太网芯片(enc28j60)驱动移植

Segmentation of Head and Neck Tumours Using Modified U-net

基于PyQt5和Qt Designer的简易加法计算器的制作

CROSSFORMER: A VERSATILE VISION TRANSFORMER BASED ON CROSS-SCALE ATTENTION

用户级线程和内核级线程

Easyexcl export 1million lines of EXECL report font error solution

五心公益红红娘团队

Self cultivation (XXI) servlet life cycle, service method source code analysis, thread safety issues
![[Huawei certification] the most complete and selected question bank in hcia-datacom history (with answer analysis)](/img/d4/f5ea847573433f7ca7bd429f57e40a.png)
[Huawei certification] the most complete and selected question bank in hcia-datacom history (with answer analysis)
随机推荐
Invalidconnectionattributeexception exception exception handling
Yotact real-time instance segmentation
c#判断数组是否包含另一个数组的任何项
The former security director of Uber faced fraud allegations and concealed the data leakage event
監控數據源連接池使用情况
Closed training (25) basic web security
Idea debugging fails, reporting jdwp no transports initialized, jvmtierror=agent_ ERROR_ TRANSPORT_ LOAD(196)
UE4 动画重定向
《网络是怎么样连接的》读书笔记 - WEB服务端请求和响应(五)
自定义mvc框架实现
长安链数据存储介绍及Mysql存储环境搭建
遍历vector容器中的对象的方式
Mac mysql数据库基本操作
爱快安装或重置后,PC或手机端获取不到ip
数据可视化:数据可视化四象限,教你正确应用图标
Implementation of multi key state machine based on STM32 standard library
数据仓库:金融/银行业的分层架构篇
【技术开发】酒精测试仪解决方案开发设计
Es error nonodeavailableexception[none of the configured nodes are available:[.127.0.0.1}{127.0.0.1:9300]
How to implement observer mode
