如何在控制器之前覆盖 SpringBoot 中的 InputStream?

How override InputStream in SpringBoot before controller?

如何在 spring 引导到达控制器之前覆盖 @RequestBody 内容?

  1. 我知道有 WebMvcConfigurerHandlerInterceptorAdapter 类 在控制器之前处理请求。

  2. 我还用谷歌搜索了 RequestBodyAdviceAdapter

有几个链接无法用于 spring 启动。

How to read request.getInputStream() multiple times

现在我可以将输入流读入字符串,进行一些修改并设置回控制器的输入流吗?

这看起来是 Servlet 过滤器的一个很好的用例。过滤器会先于控制器接收请求,允许您修改请求,然后您可以将请求传递到过滤器链中,由您的控制器处理。

示例: https://www.baeldung.com/spring-boot-add-filter

您将需要编写自定义 HttpServletRequestWrapper。在这个包装器中 class 构造函数将接收请求。将 InputStream 读入变量(此时您可以修改流)。还要将 getInputStream() 和 getReader() 方法重写为 return 您修改后的流(不是原始流)。

在您的过滤器中,创建包装器的新实例并将传入请求传递到构造函数中。完成修改后,将包装的请求传递到 chain.doFilter(myWrappedRequest, response) 以允许下游控制器处理它。

这是一个如何创建包装器并在过滤器中使用它的示例:https://howtodoinjava.com/servlets/httpservletrequestwrapper-example-read-request-body/

方案一:(个人认为更好的方案) 正如评论中所建议的那样,尝试对对象使用 @JsonProperty 或自定义 De-/Serializer。

方案二: 添加 @ControllerAdvice 并实现 RequestBodyAdvice 并覆盖 beforeBodyRead as

@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
    InputStream body = inputMessage.getBody();
    String bodyStr = IOUtils.toString(body, Charset.forName("UTF-8"));
    /*
    Update bodyStr as you wish
    */
    HttpInputMessage ret = new MappingJacksonInputMessage(new ByteArrayInputStream(bodyStr.getBytes()), inputMessage.getHeaders()); //set the updated bodyStr
    return ret;
}