Http Servlet request lose params from POST body after read it once

前端 未结 13 2107
一个人的身影
一个人的身影 2020-11-22 14:56

I\'m trying to accessing two http request parameters in a Java Servlet filter, nothing new here, but was surprised to find that the parameters have already been consumed! Be

13条回答
  •  清酒与你
    2020-11-22 15:59

    I found good solution for any format of request body. I tested for application/x-www-form-urlencoded and application/json both worked very well. Problem of ContentCachingRequestWrapper that is designed only for x-www-form-urlencoded request body, but not work with e.g. json. I found solution for json link. It had trouble that it didn't support x-www-form-urlencoded. I joined both in my code:

    import org.apache.commons.io.IOUtils;
    import org.springframework.web.util.ContentCachingRequestWrapper;
    
    import javax.servlet.ReadListener;
    import javax.servlet.ServletInputStream;
    import javax.servlet.http.HttpServletRequest;
    import java.io.BufferedReader;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class MyContentCachingRequestWrapper extends ContentCachingRequestWrapper {
    
        private byte[] body;
    
        public MyContentCachingRequestWrapper(HttpServletRequest request) throws IOException {
            super(request);
            super.getParameterMap(); // init cache in ContentCachingRequestWrapper
            body = super.getContentAsByteArray(); // first option for application/x-www-form-urlencoded
            if (body.length == 0) {
                body = IOUtils.toByteArray(super.getInputStream()); // second option for other body formats
            }
        }
    
        public byte[] getBody() {
            return body;
        }
    
        @Override
        public ServletInputStream getInputStream() {
            return new RequestCachingInputStream(body);
        }
    
        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(getInputStream(), getCharacterEncoding()));
        }
    
        private static class RequestCachingInputStream extends ServletInputStream {
    
            private final ByteArrayInputStream inputStream;
    
            public RequestCachingInputStream(byte[] bytes) {
                inputStream = new ByteArrayInputStream(bytes);
            }
    
            @Override
            public int read() throws IOException {
                return inputStream.read();
            }
    
            @Override
            public boolean isFinished() {
                return inputStream.available() == 0;
            }
    
            @Override
            public boolean isReady() {
                return true;
            }
    
            @Override
            public void setReadListener(ReadListener readlistener) {
            }
    
        }
    
    }
    

提交回复
热议问题