如何在Apache HttpClient的HttpRequestInterceptor中读取SimpleHttpRequest请求体?
问题
使用Apache HttpClient 5.x时,在HttpRequestInterceptor的process()方法中无法读取CloseableHttpAsyncClient发送的SimpleHttpRequest的请求体。示例拦截器代码如下:
class MyInterceptor implements HttpRequestInterceptor { @Override public void process(HttpRequest request, EntityDetails entity, HttpContext context) { SimpleHttpRequest simpleRequest = (SimpleHttpRequest) request; } }
这段代码会抛出ClassCastException,因为HttpRequest的实际类型是BasicHttpRequest,而BasicHttpRequest没有请求体。如何在拦截器中访问请求体?
解决方案
借助
EntityDetails参数读取请求体
拦截器process()方法的第二个参数EntityDetails就是承载请求体信息的入口,直接通过它就能获取请求体内容。示例代码:import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import org.apache.hc.core5.http.HttpException; import org.apache.hc.core5.http.HttpRequest; import org.apache.hc.core5.http.HttpContext; import org.apache.hc.core5.http.EntityDetails; import org.apache.hc.core5.http.io.HttpRequestInterceptor; class MyInterceptor implements HttpRequestInterceptor { @Override public void process(HttpRequest request, EntityDetails entity, HttpContext context) throws HttpException, IOException { if (entity != null) { // 判断请求体是否可重复读取,避免读取后后续流程无法使用 if (entity.isRepeatable()) { try (InputStream inputStream = entity.getContent()) { String bodyContent = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); // 这里添加你的请求体处理逻辑 System.out.println("读取到请求体:" + bodyContent); } } else { // 处理不可重复的请求体,可先缓存内容再生成可重复实体 byte[] bodyBytes = entity.getContent().readAllBytes(); // 替换为可重复的实体(可选,根据需求决定) entity.setContent(() -> new ByteArrayInputStream(bodyBytes)); String bodyContent = new String(bodyBytes, StandardCharsets.UTF_8); System.out.println("读取到不可重复请求体:" + bodyContent); } } } }明确请求转换逻辑
SimpleHttpRequest在发送流程中会被转换为BasicHttpRequest,所以拦截器中无法直接强转获取原实例。请求体的相关信息会被抽离到EntityDetails中,这是HttpClient 5.x拦截器中获取请求体的标准途径。
内容的提问来源于stack exchange,提问作者Peter Lustig
相关产品推荐
相关产品推荐

