1. 本章须要实现的内容
- 实现申请处理器接口 RequestProcessor 的编写
- 实现 ResultRender 渲染器接口的编写
- 实现 DefultResultRender 默认渲染器类的编写
- 实现 InternalErrorResultRender 外部异样渲染器类的编写
- 实现 JsonResultRender Json 渲染器类的编写
- 实现 ResourceNotFoundResultRender 资源未找到时应用的渲染器类编写
- 实现 ViewResultRender 页面渲染器类的编写
- 实现 DispatcherServlet http 申请拦截器的编写
- 实现 RequestProcessorChain 责任链类的编写
2. 第一局部内容
- 该局部实现 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…