从零写一个具有IOC-AOP-MVC功能的框架—学习笔记—10. MVC 结果渲染器的编写

1. 本章需要完成的内容

  1. 完成请求处理器接口RequestProcessor的编写
  2. 完成ResultRender渲染器接口的编写
  3. 完成DefultResultRender默认渲染器类的编写
  4. 完成InternalErrorResultRender内部异常渲染器类的编写
  5. 完成JsonResultRender Json渲染器类的编写
  6. 完成ResourceNotFoundResultRender 资源未找到时使用的渲染器类编写
  7. 完成ViewResultRender 页面渲染器类的编写
  8. 完成DispatcherServlet http请求拦截器的编写
  9. 完成RequestProcessorChain 责任链类的编写

2. 第一部分内容

  1. 该部分完成DispatcherServlet与RequestProcessorChain类的编写

2.1 DispatcherServlet类

2.1.1 需要完成的代码如下:

package com.wuyiccc.helloframework.mvc;

import com.wuyiccc.helloframework.aop.AspectWeaver;
import com.wuyiccc.helloframework.core.BeanContainer;
import com.wuyiccc.helloframework.injection.DependencyInjector;
import com.wuyiccc.helloframework.mvc.processor.RequestProcessor;
import com.wuyiccc.helloframework.mvc.processor.impl.ControllerRequestProcessor;
import com.wuyiccc.helloframework.mvc.processor.impl.JspRequestProcessor;
import com.wuyiccc.helloframework.mvc.processor.impl.PreRequestProcessor;
import com.wuyiccc.helloframework.mvc.processor.impl.StaticResourceRequestProcessor;
import lombok.extern.slf4j.Slf4j;

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 java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * @author wuyiccc
 * @date 2020/7/14 21:42
 * 岂曰无衣,与子同袍~
 */
@WebServlet("/*")
@Slf4j
public class DispatcherServlet extends HttpServlet {

    private static final String HELLOFRAMEWORK_CONFIG_FILE = "config/helloframework-config.properties";


    private List<RequestProcessor> PROCESSOR = new ArrayList<>();

    @Override
    public void init() throws ServletException {

        // 1. 初始化容器
        BeanContainer beanContainer = BeanContainer.getInstance();

        beanContainer.loadBeans(getHelloFrameworkScanPackages());
        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) throws ServletException, IOException {
        // 1. 创建责任链对象实例
        RequestProcessorChain requestProcessorChain = new RequestProcessorChain(PROCESSOR.iterator(), req, resp);
        // 2. 通过责任链模式来依次调用请求处理器对请求进行处理
        requestProcessorChain.doRequestProcessorChain();
        // 3. 对处理结果进行渲染
        requestProcessorChain.doRender();
    }

    private String getHelloFrameworkScanPackages() {
        Properties properties = new Properties();
        InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(HELLOFRAMEWORK_CONFIG_FILE);
        try {
            properties.load(in);
        } catch (IOException e) {
            log.warn("The config/helloframework.properties can not load");
            e.printStackTrace();
        }

        String scanPackages = properties.getProperty("helloframework.scan.packages");
        log.info("this is scanPackages: {}", scanPackages);
        return scanPackages;
    }
}

2.1.2 DIspatcherServlet类相关代码讲解:

从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---10. MVC 结果渲染器的编写

从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---10. MVC 结果渲染器的编写

2.2 RequestProcessorChain类

2.2.1 需要完成的代码如下:

package org.myframework.mvc;

/**
 * @author wuyiccc
 * @date 2020/6/16 18:48
 * 岂曰无衣,与子同袍~
 */

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.myframework.mvc.processor.RequestProcessor;
import org.myframework.mvc.render.DefaultResultRender;
import org.myframework.mvc.render.InternalErrorResultRender;
import org.myframework.mvc.render.ResultRender;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Iterator;

/**
 * 1. 以责任链的模式执行注册的请求处理器
 * 2. 委派给特定的Render实例对处理后的结果进行渲染
 */
@Data
@Slf4j
public class RequestProcessorChain {

    // 请求处理器迭代器
    private Iterator<RequestProcessor> requestProcessorIterator;

    private HttpServletRequest request;

    private HttpServletResponse response;

    // http请求方法
    private String requestMethod;

    // http请求路径
    private String requestPath;

    // http响应状态码
    private int responseCode;

    // 请求结果渲染器
    private ResultRender resultRender;


    public RequestProcessorChain(Iterator<RequestProcessor> requestProcessorIterator, HttpServletRequest request, HttpServletResponse response) {
        this.requestProcessorIterator = requestProcessorIterator;
        this.request = request;
        this.response = response;
        this.requestMethod = request.getMethod();
        this.requestPath = request.getPathInfo();
        this.responseCode = HttpServletResponse.SC_OK;
    }

    /**
     * 以责任链的模式执行请求链
     */
    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);
        }

    }


    /**
     * 执行处理器
     */
    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);
        }

    }
}

从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---10. MVC 结果渲染器的编写

从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---10. MVC 结果渲染器的编写

3. 第二部分需要完成的内容: 结果渲染器的编写

3.1 DefaultResultRender类的编写及讲解:

从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---10. MVC 结果渲染器的编写

3.2 InternalErrorResultRender类的编写及讲解:

从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---10. MVC 结果渲染器的编写

3.3 JsonResultRender类的编写及讲解:

从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---10. MVC 结果渲染器的编写

3.4 ResourceNotFoundResultRender类的编写及讲解:

从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---10. MVC 结果渲染器的编写

3.5 ViewResultRender类的编写及讲解:

从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---10. MVC 结果渲染器的编写

从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---10. MVC 结果渲染器的编写

github地址: https://github.com/wuyiccc/he…

原文 

https://segmentfault.com/a/1190000023245679

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 从零写一个具有IOC-AOP-MVC功能的框架—学习笔记—10. MVC 结果渲染器的编写

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址