如何在控制器之前覆盖 SpringBoot 中的 InputStream?
How override InputStream in SpringBoot before controller?
如何在 spring 引导到达控制器之前覆盖 @RequestBody 内容?
我知道有 WebMvcConfigurer 和 HandlerInterceptorAdapter 类 在控制器之前处理请求。
我还用谷歌搜索了 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;
}
如何在 spring 引导到达控制器之前覆盖 @RequestBody 内容?
我知道有 WebMvcConfigurer 和 HandlerInterceptorAdapter 类 在控制器之前处理请求。
我还用谷歌搜索了 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;
}