Spring HttpServletRequest 在已使用时为空

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

在获取请求正文后

Class A
Class B
正在获取空请求正文。 根据检查是否要注释
Class A
中的代码来检索请求正文,
Class B
将能够获取请求正文。

有没有办法让 HttpServletRequest 不会移除

Class A
中的请求体,Inorder
Class B
仍然可以拿到请求体?

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;
    }
java spring-boot servlets filter
1个回答
0
投票

默认情况下,请求正文只能从 HttpServletRequest 对象中使用一次。

一旦您在 A 类中读取请求正文,输入流可能会被消耗,随后尝试在 B 类中读取请求正文将导致空正文。

要解决这个问题,您可以尝试:

  • Read the Request Body Once and Cache It:
    当您读取 A 类中的请求主体时,请在处理之前将其存储在某个位置(例如,在字符串或字节数组中)。然后,你可以将这个缓存的请求体传递给B类。
  • Use HttpServletRequestWrapper to Wrap the Request:
    您可以创建 HttpServletRequestWrapper 的自定义实现,该实现重写 getInputStream() 或 getReader() 方法,以在每次调用时返回新的流或读取器。
© www.soinside.com 2019 - 2024. All rights reserved.