当前位置:网站首页>自定义MVC(上)
自定义MVC(上)
2022-07-23 05:40:00 【_Leaf1217】
目录
一、反射版增删改查
1.1 小前言
平常我们没有接触任何框架知识的时候,
我们写Web项目都是在Jsp直接跳转向servlet发送请求,
基本要实现一个功能就要建立一个servlet方便请求,但是这样会有一系列的问题,如下:
<!--
问题:
1、建的类过多;
2、新增业务的话需要修改、增加前面的代码;
3、反射相关的代码在每一个实体类对应的servlet中都存在;
4、每一个servlet中都有doget、doset方法。
-->
繁杂的代码过多,不利于我们开发,因此,今天我们来一步步尝试优化,
乃至自己编写一个MVC框架。
1.2 优化servlet类
例:A同学提出可以利用传值然后根据传过来的方法名判断要调用那个方法;
问题:
2、当我们的业务需求越来越多,需要不断的改变判断的代码,照样不够友好。
于是Leaf同学就提出了可以使用反射!(hhh开个玩笑)
确实,我们要想不改变--->判断传过来的值的代码的话就要--->想到反射的动态调用方法!
反射的一个特点就是不管你传了什么,但是反正只要你传了谁就调用谁。
所以我们尝试一下使用反射,不会使用反射的小伙伴可以参考一下我之前的文章噢,
点这里可以直接抵达:Java反射机制的基本使用__Leaf1217的博客-CSDN博客
这里直接放上servlet的代码了:
package com.leaf.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
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.catalina.filters.AddDefaultCharsetFilter;
@WebServlet("/BookServlet")
public class BookServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码方式
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
//获取输出流out
PrintWriter out = response.getWriter();
//为了区分当前请求方法,获取传过来的方法名
String ff = request.getParameter("methodName");
//拿到类类
Class<? extends BookServlet> cl = this.getClass();
try {
//拿到方法对象
Method m = cl.getDeclaredMethod(ff, HttpServletRequest.class,HttpServletResponse.class);
//打开权限
m.setAccessible(true);
//调用当前类实例的方法
m.invoke(this, request,response);
} catch (Exception e) {
e.printStackTrace();
}
}
private void add(HttpServletRequest req,HttpServletResponse resp) throws Exception {
//获取输出流out
PrintWriter out = resp.getWriter();
out.print("<script>alert('增加成功!');location.href='Test.jsp'</script>");
}
private void delete(HttpServletRequest req,HttpServletResponse resp) throws Exception {
//获取输出流out
PrintWriter out = resp.getWriter();
out.print("<script>alert('删除成功!');location.href='Test.jsp'</script>");
}
private void update(HttpServletRequest req,HttpServletResponse resp) throws Exception {
//获取输出流out
PrintWriter out = resp.getWriter();
out.print("<script>alert('修改成功!');location.href='Test.jsp'</script>");
}
private void list(HttpServletRequest req,HttpServletResponse resp) throws Exception {
//获取输出流out
PrintWriter out = resp.getWriter();
out.print("<script>alert('查询成功!');location.href='Test.jsp'</script>");
}
}1.3 测试请求
<h3>反射版增删改查</h3>
<a href="BookServlet?methodName=add">增加</a>
<a href="BookServlet?methodName=delete">删除</a>
<a href="BookServlet?methodName=update">修改</a>
<a href="BookServlet?methodName=list">查询</a>
二、自定义MVC框架工作原理图
虽然我们利用反射优化了servlet,但是还是存在一些问题:
3、反射相关的代码在每一个实体类对应的servlet中都存在;
4、每一个servlet中都有doget、doset方法。
所以,我们需要进一步的进行优化,那就是自定义一个MVC框架,
而在我们正式编写之前就需要了解一下我们设计的这个框架的工作原理图:
2.1 工作原理图
我们一起来看看分析一下这个工作原理图,运行流程:
从浏览器发送请求:
中央控制器(Action)--->子控制器(Action)--->实现处理的方法(execute)--->业务逻辑层处理(方法)
三、编写自定义MVC框架
根据我们一起分析的框架工作运行原理后,我们就可以开始逐步编码了;
3.1 建立子控制器接口:Action
package com.leaf.mvc;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 子控制器:
* 对应请求的处理人
* @author Leaf
*
* 2022年6月25日 上午9:05:41
*/
public interface Action {
void execute(HttpServletRequest req,HttpServletResponse resp);
}上面这个子控制器就是用来处理不同的请求的请求人,任何人都需要找他,
然后再由他推荐适合你的处理方法;所以我们还需要一个类实现这个万能的寻找方法:
3.2 建立实现寻找方法的类:ActionSupport
package com.leaf.mvc;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.leaf.servlet.BookServlet;
public class ActionSupport implements Action {
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp) {
//为了区分当前请求方法,获取传过来的方法名
String ff = req.getParameter("methodName");
//拿到类类
Class<? extends ActionSupport> cl = this.getClass();
try {
//拿到方法对象
Method m = cl.getDeclaredMethod(ff, HttpServletRequest.class,HttpServletResponse.class);
//打开权限
m.setAccessible(true);
//调用当前类实例的方法
m.invoke(this, req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}而这个方法类里面就是使用我们前面用过的反射来实现的~是谁的请求就调用谁的方法
所以我们就直接建立一个我们真正实现业务的方法的类:BookAction
3.3 建立方法类:BookAction
package com.leaf.servlet;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.leaf.mvc.ActionSupport;
/**
* 放真正处理业务的方法类
* @author Leaf
*
* 2022年6月25日 上午11:01:21
*/
public class BookAction extends ActionSupport {
private void add(HttpServletRequest req,HttpServletResponse resp) throws Exception {
//获取输出流out
PrintWriter out = resp.getWriter();
out.print("<script>alert('增加成功!');location.href='Test.jsp'</script>");
}
private void delete(HttpServletRequest req,HttpServletResponse resp) throws Exception {
//获取输出流out
PrintWriter out = resp.getWriter();
out.print("<script>alert('删除成功!');location.href='Test.jsp'</script>");
}
private void update(HttpServletRequest req,HttpServletResponse resp) throws Exception {
//获取输出流out
PrintWriter out = resp.getWriter();
out.print("<script>alert('修改成功!');location.href='Test.jsp'</script>");
}
private void list(HttpServletRequest req,HttpServletResponse resp) throws Exception {
//获取输出流out
PrintWriter out = resp.getWriter();
out.print("<script>alert('查询成功!');location.href='Test.jsp'</script>");
}
}3.4 建立中央控制器:DispatcherServlet
最后我们再来建立一个最初接收浏览器请求与方法名的类:中央控制器,就会理解了。
这个中央控制器的命名Leaf就不搞和工作原理图一样的了,但是地位是一样的;
package com.leaf.mvc;
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.leaf.servlet.BookAction;
/**
* 中央控制器
* 主要职能:接收浏览器请求,找到对应的处理人;
* @author Leaf
*
* 2022年6月25日 上午9:04:15
*/
//凡是以action结尾的请求的要经过总控制器
@WebServlet("*.action")
public class DispatcherServlet extends HttpServlet {
//定义一个变量储存找到的action
private Map<String, Action> actions = new HashMap<String, Action>();
@Override
public void init() throws ServletException {
//这里是请求的servlet,暂时定死,下篇文章进行优化。
actions.put("/Book", new BookAction());
}
@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();
//截取拿到--/Book---,就是最后一个/和最后一个.之间
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
//拿到请求的action
Action action = actions.get(uri);
//执行前面定义的接口的方法
action.execute(req, resp);
}
}3.5 测试请求
最后我们来试一下在前台请求测试一下是否能够实现;
<h3>框架版增删改查</h3>
<a href="Book.action?methodName=add">增加</a>
<a href="Book.action?methodName=delete">删除</a>
<a href="Book.action?methodName=update">修改</a>
<a href="Book.action?methodName=list">查询</a>
运行:


OK,好啦,今天Leaf带来的有关自定义MVC框架的学习笔记分享就到这里啦,喜欢的可以关注一下,后期可以一起学习!有不懂的地方也欢迎评论或者私信问我噢~下次见啦!!!
边栏推荐
- How to merge the website content with video and audio separated? How to write batch download code?
- The attribution of branch and loop statements in C language
- check the manual that corresponds to your MySQL server version for the right syntax to use near ‘ord
- The problem that GBK codec cannot decode may be caused by the file name
- D2DEngine食用教程(1)———最简单的程序
- 用getchar清理缓冲区(强烈推荐,C语言易错典型)
- [C language] what is a function? Classification and emphasis of functions (help you quickly classify and remember functions)
- D2DEngine食用教程(2)———绘制图像
- 【6.28】
- Transform: translate (-50%, -50%) border problem
猜你喜欢

Redis数据库和项目框架

简单实现矩形面积块

初识Flask

plsql创建Oracle数据库报错:使用Database Control配置数据库时,要求在当前Oracle主目录中配置监听程序 必须运行Netca以配置监听程序,然后才能继续。或者

Scattered notes of machine learning: some concepts and notes
D2DEngine食用教程(2)———绘制图像

Error handling of "listener not started or database service not registered" in Oracle database creation

Install pyGame using CMD

The attribution of branch and loop statements in C language

Precautions for realizing "real-time data response" on the page
随机推荐
pycharm如何正确打包ocr且让打包出来的exe尽量小
Understanding of closures of JS
Framework introduction Mvt
Machine learning algorithm for large factory interview (6) time series analysis
分页、过滤
Error when PLSQL creates Oracle Database: when using database control to configure the database, it is required to configure the listener in the current Oracle home directory. You must run netca to co
Sequencing, current limiting
How pycharm packages OCR correctly and makes the packaged exe as small as possible
Use of views
【6.28】
【Pyautogui学习】屏幕坐标、鼠标滚动
大厂面试机器学习算法(5)推荐系统算法
Matrix vector derivation in machine learning
Send SMS verification code synchronously
Py program can run, but the packaged exe prompts an error: recursion is detected when loading the "CV2" binary extension. Please check the opencv installation.
USCD行人异常数据集使用指南 | 快速下载
Pytorch white from zero uses North pointing
Web component - the lifecycle of a custom element
Scattered notes of machine learning: some concepts and notes
Pyspark learning notes