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 的子类

相关推荐
测试员周周4 分钟前
【skills5】一份 spec 生成 k6/JMeter/Locust:性能压测 + 全站截图,上线前的双保险
功能测试·网络协议·测试工具·jmeter·http·自动化·集成测试
这个DBA有点耶18 分钟前
SQL调优进阶:从“优化一条SQL”到“优化一个系统”的思维升级
java·大数据·数据库·sql·程序人生·dba·改行学it
仿生狮子1 小时前
别再说“全栈”了,AI 时代团队只认这 5 种人
前端·人工智能·后端
csdn2015_1 小时前
springboot读取配置的方法
java·spring boot·spring
AOwhisky2 小时前
下一代容器来了?Docker 宣布原生支持 WebAssembly
java·运维·docker·容器·rust·wasm
Reart3 小时前
Leetcode 213.打家劫舍2(内含闲谈,打劫真是技术活,好题,716)
后端·算法
云云只是个程序马喽3 小时前
海外短剧平台搭建方案:私有化源码系统选型|云微短剧系统技术架构拆解
java·php
触底反弹3 小时前
🔥 RAG 到底是怎么工作的?掰开揉碎了给你讲明白!
javascript·人工智能·后端
techdashen4 小时前
Go 1.26 新增 `bytes.Buffer.Peek`:只看数据,不移动读取位置
开发语言·后端·golang
Reart4 小时前
Leetcode 198.打家劫舍(716)
后端·算法