我是靠谱客的博主 腼腆乌龟,这篇文章主要介绍SpringMVC - 自研框架自研SpringMVC框架的架构图DispatcherServlet实现RequestProcessorChain实现RequestProcessor实现ResultRender实现,现在分享给大家,希望可以做个参考。
自研SpringMVC框架的架构图
DispatcherServlet实现
1、解析请求路径和请求方法
2、依赖容器,建立维护controller方法与请求的映射
3、用适合的Controller方法去处理特定的请求
实现源码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26@WebServlet("/*") public class DispatcherServlet extends HttpServlet { List<RequestProcessor> PROCESSOR = new ArrayList<>(); @Override public void init(){ //1.初始化容器 BeanContainer beanContainer = BeanContainer.getInstance(); beanContainer.loadBeans("com.imooc"); new AspectWeaver().doAop(); new DependencyInjector().doIoc(); //2.初始化请求处理器责任链 PROCESSOR.add(new PreRequestProcessor()); PROCESSOR.add(new StaticResourceRequestProcessor(getServletContext())); PROCESSOR.add(new JspRequestProcessor(getServletContext())); PROCESSOR.add(new ControllerRequestProcessor()); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) { //1.创建责任链对象实例 RequestProcessorChain requestProcessorChain = new RequestProcessorChain(PROCESSOR.iterator(), req, resp); //2.通过责任链模式来依次调用请求处理器对请求进行处理 requestProcessorChain.doRequestProcessorChain(); //3.对处理结果进行渲染 requestProcessorChain.doRender(); } }
RequestProcessorChain实现
复制代码
11.以责任链的模式执行注册的请求处理器
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19/** * 以责任链的模式执行请求链 */ public void doRequestProcessorChain() { //1.通过迭代器遍历注册的请求处理器实现类列表 try{ while(requestProcessorIterator.hasNext()){ //2.直到某个请求处理器执行后返回为false为止 if(!requestProcessorIterator.next().process(this)){ break; } }} catch (Exception e){ //3.期间如果出现异常,则交由内部异常渲染器处理 this.resultRender = new InternalErrorResultRender(e.getMessage()); log.error("doRequestProcessorChain error:", e); } }
复制代码
12.委派给特定的Render实例对处理后的结果进行渲染
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/** * 执行处理器 */ public void doRender() { //1.如果请求处理器实现类均未选择合适的渲染器,则使用默认的 if(this.resultRender == null){ this.resultRender = new DefaultResultRender(); } //2.调用渲染器的render方法对结果进行渲染 try { this.resultRender.render(this); } catch (Exception e) { log.error("doRender error: ", e); throw new RuntimeException(e); } }
RequestProcessor实现
接口定义如下
复制代码
1
2
3
4
5
6/** * 请求执行器 */ public interface RequestProcessor { boolean process(RequestProcessorChain requestProcessorChain) throws Exception; }
其中有四个实现类:
复制代码
1ControllerRequestProcessor:Controller请求处理器,处理doGet、doPost请求
复制代码
1JspRequestProcessor:jsp资源请求处理
复制代码
1PreRequestProcessor:请求预处理,包括编码以及路径处理
复制代码
1StaticResourceRequestProcessor:静态资源请求处理,包括但不限于图片、css、以及js文件等 - DefaultServlet
ResultRender实现
接口定义如下:
复制代码
1
2
3
4
5
6
7/** * 渲染请求结果 */ public interface ResultRender { //执行渲染 void render(RequestProcessorChain requestProcessorChain) throws Exception; }
实现类如下:
复制代码
1DefaultResultRender:默认渲染器
复制代码
1InternalErrorResultRender:内部异常渲染器
复制代码
1JsonResultRender:Json渲染器
复制代码
1
2
3
4
5
6
7
8
9
10
11
12@Override public void render(RequestProcessorChain requestProcessorChain) throws Exception { // 设置响应头 requestProcessorChain.getResponse().setContentType("application/json"); requestProcessorChain.getResponse().setCharacterEncoding("UTF-8"); // 响应流写入经过gson格式化之后的处理结果 try(PrintWriter writer = requestProcessorChain.getResponse().getWriter()){ Gson gson = new Gson(); writer.write(gson.toJson(jsonData)); writer.flush(); } }
复制代码
1ResourceNotFoundResultRender:资源找不到时使用的渲染器
复制代码
1ViewResultRender:页面渲染器
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34/** * 对传入的参数进行处理,并赋值给ModelAndView成员变量 * @param mv */ public ViewResultRender(Object mv) { if(mv instanceof ModelAndView){ //1.如果入参类型是ModelAndView,则直接赋值给成员变量 this.modelAndView = (ModelAndView)mv; } else if(mv instanceof String){ //2.如果入参类型是String,则为视图,需要包装后才赋值给成员变量 this.modelAndView = new ModelAndView().setView((String)mv); } else { //3.针对其他情况,则直接抛出异常 throw new RuntimeException("illegal request result type"); } } /** * 将请求处理结果按照视图路径转发至对应视图进行展示 * @param requestProcessorChain * @throws Exception */ @Override public void render(RequestProcessorChain requestProcessorChain) throws Exception { HttpServletRequest request = requestProcessorChain.getRequest(); HttpServletResponse response = requestProcessorChain.getResponse(); String path = modelAndView.getView(); Map<String, Object> model = modelAndView.getModel(); for(Map.Entry<String, Object> entry : model.entrySet()){ request.setAttribute(entry.getKey(), entry.getValue()); } //JSP request.getRequestDispatcher(VIEW_PATH +path).forward(request, response); }
最后
以上就是腼腆乌龟最近收集整理的关于SpringMVC - 自研框架自研SpringMVC框架的架构图DispatcherServlet实现RequestProcessorChain实现RequestProcessor实现ResultRender实现的全部内容,更多相关SpringMVC内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复