Bob
Bob

Reputation: 157

Post request data lost after using custom filter and custom requestWrapper in Spring boot

I am writing a Spring boot filter to verify request data before it hits the rest controller. To avoid HttpServletRequest read ServletInputStream twice, I writed a CustomRequestWrapper to wrap it. But When I send a post request(conetentType = "multipart/form-data") by postman , I get a null in rest controller.

Here is my filter:

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        CustomReqeustWrapper requestWrapper = new CustomReqeustWrapper(req);
        CustomResponseWrapper responseWrapper = new CustomResponseWrapper(resp);

        // get requestBody from requestWrapper and verify.
        readContent(requestWrapper);
        chain.doFilter(requestWrapper, responseWrapper);
        writeContent(response);
    }

Here is my RequestWrapper:

public class CustomRequestWrapper extends HttpServletRequestWrapper {

    private byte[] requestBody = new byte[0];

    public CustomRequestWrapper (HttpServletRequest request) {
        super(request);
        try {
            requestBody = StreamUtils.copyToByteArray(request.getInputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return bais.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setReadListener(ReadListener listener) {

            }
        };
    }

    public byte[] getRequestData() {
        return requestBody;
    }

    public void setRequestData(byte[] requestData) {
        this.requestBody = requestData;
    }
}

Here is my controller:

    @PostMapping("/exchange")
    public ResponseEntity<Void> keyExchange(HttpServletRequest request, String Key) throws Exception {
      // get the "key" is null.
    }

Upvotes: 1

Views: 686

Answers (1)

ediron
ediron

Reputation: 65

If the type of parameter 'key' is String,maybe you should't use 'multipart' data type.

For all I know,I had met this problem once.The wrapper is useless for file parameter.

If you have to use 'multipart' type,perhaps you should use other manner to figure out it.

Upvotes: 1

Related Questions