手把手写框架入门(一) | 核心拦截器DispatchFilter实现
前言
【课程目标】
深入理解Java Web核心开发
掌握框架开发的必备知识
具备自主编写Web开发框架的思路【课程目标】
本教程内容基于伟大的Struct2框架原理进行学习,本教程只是个人学习的记录,仅供大家学习交流,不作为任何商业用途
【课程思想】
先构思整体基本设计思路,再逐一实现每个模块的具体逻辑,一开始不必要太在意细节,先让整个流程跑通,再慢慢优化框架
1Filter实现框架拦截
【课前思考】
1.Filter的作用是什么?
2.Filter什么时候加载
3.框架是如何根据用户请求找到对应的处理类和处理方法
4.框架是如何执行用户请求
1.1配置自定义Filter
想在项目中用上我们自己的框架,需要在web.xml中配置我们自己实现的Filter,容器在启动时会帮我们初始化该过滤器
<filter>
<filter-name>dispatchFilter</filter-name>
<filter-class>com.eshare.core.filter.DispatchFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>dispatchFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.2创建一个Filter
该filter作为我们的请求的核心转发器,命名为DispatchFilter,帮我们转发请求到对应的Action中处理
该filter功能如下:
1.获取用户请求
2.根据用户请求找到对应的映射类(ActionMapping)
3.如果找到匹配的映射类,则执行用户请求,否则,继续执行其他环节
【思路】
1.通过ActionMapper去找到用户请求对应的映射类actionMapping
2.通过WebExecutor去执行actionMapping的对应的处理类和方法
模块:
1.ActionMapper 此处用于管理映射类
2.ActionMapping 此处用于管理处理类的全限定名、处理方法名
3.WebExecutor 此处用于根据对应的actionMapping统一执行用户请求
public class DispatchFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//filter执行过滤器
System.out.println("dispatchFilter开始执行");
//根据请求找到对应的mapping类
ActionMapper actionMapper = new ActionMapper();
ActionMapping mapping =actionMapper.findMapping(request);
if(mapping!=null){
WebExecutor executor = new WebExecutor();
//执行用户请求
executor.execute(request,response,mapping);
}else {
//非框架处理部分,继续执行其他环节
chain.doFilter(request, response);
}
}
public void destroy() {
}
}
1.3创建一个ActionMapping
由第二节可以得知,ActionMapping在本章内容是用来管理具体处理类和处理方法的,所以它应该有属性去记录处理类的全限定名和处理方法的方法名,以便于以后框架反射执行处理方法
【思路】
ActionMapping主要用于映射配置的,要让框架获取到该类实例时,可以调用框架使用者用于处理请求的具体类和方法并且以某种形式响应给调用者,我们可以猜想反射需要用到的条件,就是全限定名和具体方法名,还有处理完成以什么形式响应给用户
属性:
1.className 处理类的全限定名
2.methodName 处理类的处理方法
3.result 返回结果(如jsp、file)
public class ActionMapping {
/**
* 类全限定名
*/
private String className;
/**
* 方法名
*/
private String methodName;
/**
* 返回结果
*/
private String result;
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
1.4创建一个ActionMapper
由第二节可以得知,ActionMapper在本章内容就是用来管理映射类的,那么它需要有findMapping这样的方法用于查找映射类,这样可以根据用户的请求参数来查找到对应的映射类ActionMapping
PS:在本章暂时用硬编码方式实现基本功能,后面再做优化,本章例子使用PersonAction作为请求处理类
【思路】
通过ActionMapper的findMapping方法,根据用户的请求参数,查找到对应的映射类ActionMapping,然后返回该映射类
public class ActionMapper {
public ActionMapping findMapping(ServletRequest request) {
ActionMapping actionMapping = new ActionMapping();
actionMapping.setClassName("com.eshare.action.PersonAction");
actionMapping.setMethodName("hello");
return actionMapping;
}
}
1.5创建一个WebExecutor
由第二节可以得知,webExecutor在本章内容是用于根据具体的映射类actionMapping去执行用户请求,它应该有一个execute执行方法,用于执行actionMapping具体的处理方法,并响应给用户
【思路】
通过WebExecutor中的execute方法,框架可以统一反射调用映射类中的具体实现方法,来执行用户请求
public class WebExecutor {
public void execute(ServletRequest request, ServletResponse response, ActionMapping mapping) {
//获取执行请求的类名
String className = mapping.getClassName();
//获取执行请求的方法
String methodName =mapping.getMethodName();
try {
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();
Method method = clazz.getMethod(methodName,null);
//执行方法
method.invoke(obj,null);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
1.6创建测试类PersonAction
PersonAction在本章内容是用于模拟框架使用者自定义的处理类,它里面包含一个hello方法,是框架使用者自定义的一个方法,本章主要围绕着该方法,看框架如何通过请求一步步找到hello这方法,并执行
首先我们在test/java目录下创建一个PersonAction,避免代码结构混乱,因为主目录是用来存放框架代码
public class PersonAction {
public String hello(){
System.out.println("hello");
boolean flag = false;
if(flag){
return "SUCCESS";
}else {
return "FAILE";
}
}
}
1.7最终工程目录结构
2测试Filter
2.1启动tomcat
2.2在浏览器输入URL
我的上下文路径是eshare
http://localhost:8080/eshare/hello
2.3查看控制台输出结果
3本章源码地址
Github:https://github.com/Evan43789596/FrameworkDesign.git
手把手写框架入门(一) | 核心拦截器DispatchFilter实现的更多相关文章
- MVC框架的插件与拦截器基础
自制MVC框架的插件与拦截器基础 上篇谈到我自己写的MVC框架,接下来讲讲插件及拦截器! 在处理一些通用的逻辑最好把它封装一个插件或者拦截器,以便日后可以直接拿过来直接使用.在我的框架中可以通过继承以 ...
- Dora.Interception,为.NET Core度身打造的AOP框架 [3]:多样化拦截器应用方式
在<以约定的方式定义拦截器>中,我们通过对拦截器的介绍了Dora.Interception的两种拦截机制,即针对接口的“实例拦截”针对虚方法的“类型拦截”.我们介绍了拦截器的本质以及基于约 ...
- Struts2的核心——拦截器
虽然以前已经学了很多的拦截器,但是在这里还是想重头梳理一下所有有关拦截器的知识,尤其是struts2中的拦截器 1:拦截器是什么? java里的拦截器是动态拦截Action调用的对象.它提供了一种机制 ...
- java框架之Struts2(4)-拦截器&标签库
拦截器 概述 Interceptor (拦截器):起到拦截客户端对 Action 请求的作用. Filter:过滤器,过滤客户端向服务器发送的请求. Interceptor:拦截器,拦截的是客户端对 ...
- 自制MVC框架的插件与拦截器基础
上篇谈到我自己写的MVC框架,接下来讲讲插件及拦截器! 在处理一些通用的逻辑最好把它封装一个插件或者拦截器,以便日后可以直接拿过来直接使用.在我的框架中可以通过继承以下抽象类来实现插件或者拦截器. 1 ...
- 秒极啊!手把手带你进行shiro授权拦截器的重写,学到了学到了
shiro整合前后端分离的springboots,Vue项目真的是有很多大坑啊. 今天我的主题是:如何设置shiro过滤器. 遇到问题:我的项目是前后端分离的,shiro里面有一个shiroFilte ...
- Struts2入门(二)——配置拦截器
一.前言 之前便了解过,Struts 2的核心控制器是一个Filter过滤器,负责拦截所有的用户请求,当用户请求发送过来时,会去检测struts.xml是否存在这个action,如果存在,服务器便会自 ...
- Struts2(五)——核心拦截器
Struts框架一共为我们提供了35个拦截器,其中默认的拦截器有18个,框架访问action的异常处理,配置信息处理,转发重定向选择,上传等等等等,都是这18个拦截器中设置的,起着非比寻常的作用.而这 ...
- java框架篇---struts实现拦截器
Struts2的拦截器和Servlet过滤器类似.在执行Action的execute方法之前,Struts2会首先执行在struts.xml中引用的拦截器,在执行完所有引用的拦截器的intercept ...
随机推荐
- 配置一个yum私有仓库
使用一台服务器配置私有仓库做yum源,本身使用file,客户端使用http连接 安装http服务: [root@ceph1 ~]# yum -y install httpd 修改配置文件 Docume ...
- VC/c++版本获取现行时间戳精确到毫秒
时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数.通俗的讲, 时间戳是一份能够表示一份数据在一个特定时间点已经存在的完 ...
- 洛谷$P3226\ [HNOI2012]$集合选数 状压$dp$
正解:$dp$ 解题报告: 传送门$QwQ$ 考虑列一个横坐标为比值为2的等比数列,纵坐标为比值为3的等比数列的表格.发现每个数要选就等价于它的上下左右不能选. 于是就是个状压$dp$板子了$QwQ$ ...
- 洛谷$P2570\ [ZJOI2010]$贪吃的老鼠 网络流+二分
正解:网络流+二分 解题报告: 传送门$QwQ$ 和上一题有点儿像,,,?$QwQ$但是比上一题要有趣很多$QwQ$ 首先把大致思路捋下?依然是.二分出每个奶酪的开始和结束时间,然后check下最大流 ...
- $[NOIp2017]$ 逛公园 $dp$/记搜
\(Des\) 给定一个有向图,起点为\(1\),终点为\(n\),求和最短路相差不超过\(k\)的路径数量.有\(0\)边.如果有无数条,则输出\(-1\). \(n\leq 10^5,k\leq ...
- Python 打包——过去、现在与未来
英文 | Python packaging - Past, Present, Future[1] 原作 | BERNAT GABOR 译者 | 豌豆花下猫 声明 :本文获得原作者授权翻译,转载请保留原 ...
- 【一起学源码-微服务】Ribbon 源码四:进一步探究Ribbon的IRule和IPing
前言 前情回顾 上一讲深入的讲解了Ribbon的初始化过程及Ribbon与Eureka的整合代码,与Eureka整合的类就是DiscoveryEnableNIWSServerList,同时在Dynam ...
- Java和JavaScript之间的区别
1.简介 通过优锐课核心java学习笔记中,我们可以看到,Java和JavaScript之间的区别.我们将在本文中比较Java语言和JavaScript语言.JavaScript由Netscape开发 ...
- Quartz.NET总结(八)如何根据自己需要配置Topshelf 服务
前面讲了如何使用Topshelf 快速开发windows服务, 不清楚的可以看之前的这篇文章:https://www.cnblogs.com/zhangweizhong/category/771057 ...
- Netty快速入门(06)Netty介绍
前面简单的介绍了Java I/O 和NIO,写了示例程序. Java I/O是阻塞的,为了让它支持多个并发,就要针对每个链接启动线程,这种方式的结果就是在海量链接的情况下,会创建海量的线程,就算用线程 ...