Write a framework with ioc-aop-mvc function from scratch — learning notes — 10. The writing of MVC result render

Time:2021-1-26

1. What should be done in this chapter

  1. Complete the writing of request processor interface
  2. Finish writing the interface of resultrender
  3. Finish the writing of default render class of faultresultrender
  4. Complete the writing of the internal exception render class of internalerrorresulterrender
  5. Complete the jsonresultrender JSON render class
  6. Complete the writing of the render class used when resourcenotfoundresultrender resource is not found
  7. Complete the writing of the viewresultrender page render class
  8. Complete the writing of HTTP request interceptor for dispatcherserservlet
  9. Complete the writing of requestprocessorchain responsibility chain class

2. The first part

  1. This part completes the writing of dispatcherservlet and requestprocessorchain classes

2.1 dispatcherservlet class

2.1.1 the code to be completed is as follows:
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
 *Do you say that you have no clothes, and you are in the same robe with your son~
 */
@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. Initialize the container
        BeanContainer beanContainer = BeanContainer.getInstance();

        beanContainer.loadBeans(getHelloFrameworkScanPackages());
        new AspectWeaver().doAop();
        new DependencyInjector().doIoc();
        //2. Initialize the responsibility chain of request processor
        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. Create an instance of responsibility chain object
        RequestProcessorChain requestProcessorChain = new RequestProcessorChain(PROCESSOR.iterator(), req, resp);
        //2. Call the request processor in turn to process the request through the responsibility chain mode
        requestProcessorChain.doRequestProcessorChain();
        //3. Render the result
        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 related code explanation of dspatcherservlet class:

Write a framework with ioc-aop-mvc function from scratch -- learning notes -- 10. The writing of MVC result render

Write a framework with ioc-aop-mvc function from scratch -- learning notes -- 10. The writing of MVC result render

2.2 requestprocessorchain class

2.2.1 the code to be completed is as follows:
package org.myframework.mvc;

/**
 * @author wuyiccc
 * @date 2020/6/16 18:48
 *Do you say that you have no clothes, and you are in the same robe with your son~
 */

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. Execute the registered request processor in the mode of responsibility chain
 *2. Delegate to a specific render instance to render the processed results
 */
@Data
@Slf4j
public class RequestProcessorChain {

    //Request processor iterator
    private Iterator<RequestProcessor> requestProcessorIterator;

    private HttpServletRequest request;

    private HttpServletResponse response;

    //HTTP request method
    private String requestMethod;

    //HTTP request path
    private String requestPath;

    //HTTP response status code
    private int responseCode;

    //Request result render
    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;
    }

    /**
     *Executing request chain in the mode of responsibility chain
     */
    public void doRequestProcessorChain() {
        //1. Iterator traverses the registered request processor to realize class list
        try {
            while (requestProcessorIterator.hasNext()) {
                //2. Until a request processor returns false after execution
                if (!requestProcessorIterator.next().process(this)) {
                    break;
                }
            }
        } catch (Exception e) {
            //3. If there is an exception during the process, it will be handled by the internal exception render
            this.resultRender = new InternalErrorResultRender(e.getMessage());
            log.error("doRequestProcessorChain error: ", e);
        }

    }


    /**
     *Executive processor
     */
    public void doRender() {
        //1. If the request processor implementation class does not select an appropriate render, the default is used
        if (this.resultRender == null) {
            this.resultRender = new DefaultResultRender();
        }
        //2. Call render method to render the result
        try {
            this.resultRender.render(this);
        } catch (Exception e) {
            log.error("doRender error: ", e);
            throw new RuntimeException(e);
        }

    }
}

Write a framework with ioc-aop-mvc function from scratch -- learning notes -- 10. The writing of MVC result render

Write a framework with ioc-aop-mvc function from scratch -- learning notes -- 10. The writing of MVC result render

3. The second part: the writing of result render

3.1 writing and explanation of the defaultresultrender class:

Write a framework with ioc-aop-mvc function from scratch -- learning notes -- 10. The writing of MVC result render

3.2 writing and explanation of internalerrorresulterrender class:

Write a framework with ioc-aop-mvc function from scratch -- learning notes -- 10. The writing of MVC result render

3.3 writing and explanation of jsonresultrender class:

Write a framework with ioc-aop-mvc function from scratch -- learning notes -- 10. The writing of MVC result render

3.4 writing and explanation of resourcenotfoundresultrender class:

Write a framework with ioc-aop-mvc function from scratch -- learning notes -- 10. The writing of MVC result render

3.5 writing and explanation of viewresultrender class:

Write a framework with ioc-aop-mvc function from scratch -- learning notes -- 10. The writing of MVC result render

Write a framework with ioc-aop-mvc function from scratch -- learning notes -- 10. The writing of MVC result render

GitHub address: https://github.com/wuyiccc/he…