代码之家  ›  专栏  ›  技术社区  ›  RedBlue

Spring HttpServlet请求在已使用时为空

  •  0
  • RedBlue  · 技术社区  · 1 年前

    Class A 在获得请求正文后 Class B 正在获取空的请求正文。 根据检查是否要在中注释代码 A类 为了检索请求主体, B类 将能够获得请求正文。

    有没有办法使HttpServlet请求不会删除中的请求主体 A类 ,订单 B类 仍然可以获得请求正文?

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

    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;
        }
    
    1 回复  |  直到 1 年前
        1
  •  3
  •   NeveMore    1 年前

    默认情况下,HttpServlet请求对象只能使用一次请求体。

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

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

    • Read the Request Body Once and Cache It: 当你在类A中读取请求体时,在处理它之前将其存储在某个地方(例如,字节数组中)。然后,你可以将这个缓存的请求体传递给类B。
    • Use HttpServletRequestWrapper to Wrap the Request: 您可以创建HttpServletRequestWrapper的自定义实现,该实现覆盖getInputStream()或getReader()方法,以在每次调用时返回一个新流或读取器。

    以下是一个示例: https://www.baeldung.com/spring-reading-httpservletrequest-multiple-times