从零写一个具有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 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 结果渲染器的编写_第1张图片

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

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 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 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 结果渲染器的编写_第3张图片

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

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

3.1 DefaultResultRender类的编写及讲解:

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

3.2 InternalErrorResultRender类的编写及讲解:

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

3.3 JsonResultRender类的编写及讲解:

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

3.4 ResourceNotFoundResultRender类的编写及讲解:

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

3.5 ViewResultRender类的编写及讲解:

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

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

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

你可能感兴趣的:(java,spring,后端,springboot)