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

相关推荐
麻瓜生活睁不开眼6 分钟前
Android16修改全局桌面视图边框四直角显示为弧边圆角
android·java·深度学习
dear_bi_MyOnly23 分钟前
【MyBatis 操作数据库】
java·数据库·学习·mybatis·学习方法
2601_953720821 小时前
【计算机毕业设计】基于Spring Boot的心理健康咨询与评测系统的设计与实现
java·spring boot·后端
丈剑走天涯2 小时前
JDK 17 正式特性
java·开发语言
东方小月2 小时前
从零开发一个 Coding Agent(四):使用状态机校验大模型事件流
前端·人工智能·后端
圣光SG2 小时前
Java操作题练习(七)
java·开发语言·算法
都叫我大帅哥2 小时前
“让AI修就行”?我劝你收回这句话——来自一位Java博主的硬核反常识
后端
whyfail3 小时前
前端学 Spring Boot(8):接口为什么越用越慢?
前端·spring boot·后端
q567315234 小时前
企业级 HTTP 代理采购选型:技术评估清单 15 项
开发语言·网络·爬虫·网络协议·http·隧道ip·代理ip