javaspring-bootservletsfilter

Spring HttpServletRequest is empty when already used


At Class A after getting the request body, The Class B is getting empty request body. As per checking if going to comment the code in Class A to retrieve the request body, Class B will able to get the request body.

Is there a way to make HttpServletRequest will not remove the request body in Class A, Inorder Class B can still get the request body?

Class A


@Autowired
        private HttpServletRequest request;
  

 public Authentication authenticate(Authentication authentication) throws AuthenticationException {

 String requestBody =  extractBody(request);
            System.out.println("Request Body1: "+requestBody);

....other codes



}

   public static String extractBody(HttpServletRequest request){
        String body = null;
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;

        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            try {
                throw ex;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    try {
                        throw ex;
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }

        body = stringBuilder.toString();
        return body;
    }

Class B

  public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {

 String requestBody =  extractBody(request);
            System.out.println("Request Body2: "+requestBody);

....other codes

  

}

 public static String extractBody(HttpServletRequest request){
        String body = null;
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;

        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            try {
                throw ex;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    try {
                        throw ex;
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }

        body = stringBuilder.toString();
        return body;
    }

Solution

  • Request body can be consumed only once from the HttpServletRequest object by default.

    Once you read the request body in Class A, the input stream might be consumed, and subsequent attempts to read it in Class B will result in an empty body.

    To address this issue, you can try:

    Here is an example: https://www.baeldung.com/spring-reading-httpservletrequest-multiple-times