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

50次阅读

共计 4968 个字符,预计需要花费 13 分钟才能阅读完成。

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 类相干代码解说:

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);
        }

    }
}

3. 第二局部须要实现的内容:后果渲染器的编写

3.1 DefaultResultRender 类的编写及解说:

3.2 InternalErrorResultRender 类的编写及解说:

3.3 JsonResultRender 类的编写及解说:

3.4 ResourceNotFoundResultRender 类的编写及解说:

3.5 ViewResultRender 类的编写及解说:

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

正文完
 0