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

相关推荐
钱多多_qdd7 分钟前
spring cache源码解析(四)——从@EnableCaching开始来阅读源码
java·spring boot·spring
waicsdn_haha9 分钟前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
飞的肖17 分钟前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
Q_192849990619 分钟前
基于Spring Boot的摄影器材租赁回收系统
java·spring boot·后端
Code_流苏22 分钟前
VSCode搭建Java开发环境 2024保姆级安装教程(Java环境搭建+VSCode安装+运行测试+背景图设置)
java·ide·vscode·搭建·java开发环境
良许Linux24 分钟前
0.96寸OLED显示屏详解
linux·服务器·后端·互联网
青灯文案125 分钟前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
求知若饥36 分钟前
NestJS 项目实战-权限管理系统开发(六)
后端·node.js·nestjs
禁默1 小时前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程
Cachel wood1 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架