使用场景:
-
想实现自定义协议请求数据,但是还有拥有spring的 controller方便的业务处理流程和注解。
-
想要调用对应的 controller 却不想处理自定义的 mapping。
一、首先是通过参考 spring-test 中的模拟实现的HttpServlet
XML
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
二、参考已经实现的模拟javax.servlet.http.HttpServletRequest 和 javax.servlet.http.HttpServletResponse
在 spring-test 依赖中已经对以上两个接口实现分别是
org.springframework.mock.web.MockHttpServletRequest
org.springframework.mock.web.MockHttpServletResponse
还会依赖到 org.springframework.mock.web.HeaderValueHolder 封装的请求头
可以把这三个类复制出来进行自定义改造
三、调用Spring的HTTP请求处理程序类 org.springframework.web.servlet.DispatcherServlet
通过此类中的 protected void service (HttpServletRequest request, HttpServletResponse response) 方法。 service通过将标准 HTTP 请求分派给每种 HTTP 请求类型的处理程序方法(do上面列出的 Method 方法)来处理标准 HTTP 请求。
形参:
reqHttpServletRequest-- 包含客户端对 servlet 发出的请求的对象
respHttpServletResponse-- 包含 servlet 返回给客户端的响应的对象
请求可以使用MockHttpServletRequest 的实现类 MockHttpServletRequest 传入service方法来处理请求,如果需要自定义可以复制 MockHttpServletRequest 类进行修改。
注意 service 是 protected修饰的,可以直接继承 DispatcherServlet 来调用service方法。
四、直接调用处理请求会出现 No mapping for GET XXX
因为没有初始化 mapping 未找到→设置适当的 HTTP 响应状态的处理程序。所以请求走到了方法 noHandlerFound(HttpServletRequest request, HttpServletResponse response)
需要在构造自己的调度器时初始化一下。
以下是自己实现的Servlet调度器示例:
java
public class MyDispatcherServlet extends DispatcherServlet {
public MyDispatcherServlet() {
super();
// 初始化mapping
onRefresh(SpringUtils.applicationContext);
}
public void processRequest() {
try {
// 创建自定义的ServletRequest和ServletResponse
MockHttpServletRequest servletRequest = new MockHttpServletRequest();
MockHttpServletResponse servletResponse = new MockHttpServletResponse();
// 设置请求参数
servletRequest.setMethod(); // 或者POST等
servletRequest.setRequestURI();
servletRequest.setContent(); // 假设TcpRequest有一个getContent方法
servletRequest.setContentType(); // 假设TcpRequest有一个getContentType方法
// 请求父类服务
service(servletRequest, servletResponse);
// 获取请求结果
System.out.println(servletResponse.getContentAsByteArray());
System.out.println(servletResponse.getStatus());
} catch (Exception e) {
e.printStackTrace();
}
}
其他实现可以参考示例 org.springframework.test.web.servlet.TestDispatcherServlet
他们都是 Java 中 javax.servlet.http.HttpServlet 的子类