我是一个新的javaer。最近在做一个新的springboot项目,想在进入mvc controller之前打印request body。 (确切地说,我想打印 contentType:"application/json" 的 post 请求正文)
我使用如下的 requestWrapper。
public class MyRequestWrapper extends HttpServletRequestWrapper {
private byte[] cachedBody = new byte[]{};
private InputStream input = null;
public MyRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
if (request.getContentType() != null && (request.getContentType().contains("multipart/") ||
request.getContentType().contains("/x-www-form-urlencoded"))) {
cachedBody = new byte[]{};
input = request.getInputStream();
} else {
cachedBody = StreamUtils.copyToByteArray(request.getInputStream());
input = new ByteArrayInputStream(cachedBody);
}
}
@Override
public ServletInputStream getInputStream() {
return new ServletInputStream() {
@Override
public int read() throws IOException {
return input.read();
}
}
}
public String getBody() {
return new String(cachedBody);
}
然后,我使用过滤器打印请求内容。
@WebFilter(filterName = "RequestResponseFilter", urlPatterns = "/*", asyncSupported = true)
public class RequestResponseFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
MyRequestWrapper requestWrapper = (MyRequestWrapper) request;
......
System.out.println(requestWrapper.getBody());
......
chain.doFilter(requestWrapper, response);
}
}
下面是我的控制器。
@PostMapping(value="/test")
public ResponseData<String> test(
@RequestParam("id") String id,
@RequestParam("value") String value) {
ResponseData<String> result = new ResponseData<>();
result.setData(id + value);
result.setCode(Constants.CODE_SUCCESS);
return result;
}
然而,当我使用邮递员测试我的代码时,它并没有很好地工作。如果我使用 post 方法并通过内容类型传递参数:“application/x-www-form-urlencoded”,它会抛出“org.springframework.web.bind.MissingServletRequestParameterException”。
让我困惑的是,如果我传递带有内容类型的参数:“multipart/form-data”,它工作得很好。
此外,我尝试了spring提供的CachedBodyHttpServletRequest。但是在请求进入控制器之前,它无法获取请求内容。
为什么mvc controller 获取注解为@RequestParam 的param 失败?我该如何解决?
你可以像这样得到参数和身体
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// param
request.getParameterMap().forEach((k, v) -> System.out.println(k + " : " + v[0]));
// body
byte[] array = StreamUtils.copyToByteArray(request.getInputStream());
System.out.println(new String(array, StandardCharsets.UTF_8));
}
但是如果你用
multipart/form-data
上传文件然后文件内容不能转换成字符串,你需要工具来解决它,像这样
if (contentType.startsWith("multipart/form-data")) {
StandardServletMultipartResolver resolver = new StandardServletMultipartResolver();
StandardMultipartHttpServletRequest req = (StandardMultipartHttpServletRequest)resolver.resolveMultipart((HttpServletRequest) request);
System.out.println(req.getMultiFileMap());
System.out.println(req.getParameterMap());
}
您可以在这里阅读文章:链接
但是对于 multipart/form-data,更改类以在下面扩展: 公共类 CachedBodyHttpServletFormRequest 扩展 StandardMultipartHttpServletRequest {}