SpringBoot内部模拟http请求到Controller(不通过本机网络)

使用场景:

  1. 想实现自定义协议请求数据,但是还有拥有spring的 controller方便的业务处理流程和注解。

  2. 想要调用对应的 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 的子类

相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
小羊没烦恼!2 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
俊昭喜喜里3 天前
java中的继承和多态的区别
java
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
譕痕3 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖3 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时3 天前
01-06-A-JVM排查实战详解
java·jvm