多次使用request body的问题

问题描述 投票:0回答:2

我是一个新的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 失败?我该如何解决?

java spring-mvc servlets httprequest
2个回答
1
投票

你可以像这样得到参数和身体

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());
}

0
投票

您可以在这里阅读文章:链接

但是对于 multipart/form-data,更改类以在下面扩展: 公共类 CachedBodyHttpServletFormRequest 扩展 StandardMultipartHttpServletRequest {}

© www.soinside.com 2019 - 2024. All rights reserved.