Spring Boot 使用ContainerRequestContext获取并打印请求正文

dm7nw8vv  于 2023-04-11  发布在  Spring
关注(0)|答案(1)|浏览(382)

bounty还有2天到期。回答此问题可获得+50声望奖励。jane希望引起更多关注此问题。
我有下面的代码,我试图使用ContainerRequestContext获取和打印请求流的实体。然而,在我读取输入流之后,它中断了API调用。我能够使用getter(如responseContext.getURiInfo)从“ContainerRequestContext”获取其他细节()等。请注意,我不想在任何地方使用“ReaderInterceptor”和Lombok岛的“aroundReadFrom”。任何帮助都很感激。谢谢!
**UPDATE:**请求的payload为“x-www-form-urlencoded”,阅读后如何将请求的payload设置回“x-www-form-urlencoded”?这可能是我读取payload后请求失败的原因,我可能没有正确设置“setEntityStream()”。

public String getRequestEntityStream(ContainerRequestContext requestContext) throws IOException {

        try (InputStream in = requestContext.getEntityStream()) {
            ByteArrayOutputStream out = new ByteArrayOutputStream(64 * 1024);
            IOUtils.copy(in, out);
            byte[] entity = out.toByteArray();
            //restore input
            requestContext.setEntityStream(new ByteArrayInputStream(entity));
            String str=new String(entity);  
            
            return str;
        }
    }

我使用上面的如下方式来追加到StringBuilder:

@Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        StringBuilder sbRequest = new StringBuilder();
        
        sbRequest.append(" - Request Entity Stream : ").append(getRequestEntityStream(requestContext));
    
    }
crcmnpdw

crcmnpdw1#

尝试使用ContainerRequestContext获取请求流的实体时得到null的原因是,在调用IOUtils.copy(in,out)时正在读取和使用输入流。
一旦流被读取,流指针就到达流的末尾,并且没有更多的字节可供读取。因此,当您在输入流被读取之后尝试使用requestContext.getEntityStream()访问请求实体流时,它返回null。
要修复此问题,您可以使用实体字节数组创建ByteArrayInputStream的新示例,并在返回实体字符串之前使用requestContext.setEntityStream()将其设置回ContainerRequestContext。这将确保请求实体流重置为其初始状态,并且您可以在需要时再次访问它。
请试试这个:

public String getRequestEntityStream(ContainerRequestContext requestContext) throws IOException {

    try (InputStream in = requestContext.getEntityStream()) {
        ByteArrayOutputStream out = new ByteArrayOutputStream(64 * 1024);
        IOUtils.copy(in, out);
        byte[] entity = out.toByteArray();
        
        //reset the input stream
        ByteArrayInputStream inNew = new ByteArrayInputStream(entity);
        requestContext.setEntityStream(inNew);

        String str = new String(entity);
        return str;
    }
}

相关问题