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

相关推荐
code_YuJun5 分钟前
Spring ioc 完全注解
后端
kevinzeng6 分钟前
反射的初步理解
后端·面试
下次一定x8 分钟前
深度解析 Kratos 客户端服务发现与负载均衡:从 Dial 入口到 gRPC 全链路落地(上篇)
后端·go
kevinzeng10 分钟前
Spring 核心知识点:EnvironmentAware 接口详解
后端
xyy12310 分钟前
C# / ASP.NET Core 依赖注入 (DI) 核心知识点
后端
yuhaiqiang1 小时前
为什么我建议你不要只问一个AI?🤫偷偷学会“群发”,答案准到离谱!
人工智能·后端·ai编程
双向332 小时前
AR 眼镜拯救社恐:我用 Kotlin 写了个拜年提词器
后端
吾日三省Java2 小时前
Spring Cloud架构下的日志追踪:传统MDC vs 王炸SkyWalking
java·后端·架构
想打游戏的程序猿3 小时前
服务端用AI写前端:隐患、困境与思考
后端
爱玩泥巴的小t3 小时前
new Thread().start()底层做了什么?
java