是否有第三方库可实现HttpServletRequest转org.apache.http.HttpRequest?
有没有现成库可以将
HttpServletRequest转为org.apache.http.HttpRequest? 当然有现成的第三方库可以帮你完成这个转换,不用手动去复制请求头、请求体这些繁琐的内容。下面是几个常用的方案:
1. 使用Spring Framework的工具类
如果你已经在使用Spring(尤其是Spring Web),这是最方便的选择,Spring提供了现成的类来简化Servlet请求到Apache HttpClient请求的转换:
首先确保你的项目引入了Spring Web依赖(Maven示例):
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.24</version> <!-- 替换为你项目对应的版本 --> </dependency>
然后可以这样实现转换:
import org.springframework.http.server.ServletServerHttpRequest; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ByteArrayEntity; import org.apache.commons.io.IOUtils; import javax.servlet.http.HttpServletRequest; import java.io.IOException; public org.apache.http.HttpRequest convertToApacheHttpRequest(HttpServletRequest servletRequest) throws IOException { // 用Spring包装Servlet请求,自动处理请求头、请求体的基础封装 ServletServerHttpRequest wrappedRequest = new ServletServerHttpRequest(servletRequest); // 根据请求方法创建对应的Apache HttpRequest实例 HttpUriRequest apacheRequest; switch (wrappedRequest.getMethod()) { case GET: apacheRequest = new HttpGet(wrappedRequest.getURI()); break; case POST: apacheRequest = new HttpPost(wrappedRequest.getURI()); // 处理POST请求的请求体 if (wrappedRequest.getBody().available() > 0) { byte[] bodyBytes = IOUtils.toByteArray(wrappedRequest.getBody()); ((HttpPost) apacheRequest).setEntity(new ByteArrayEntity(bodyBytes)); } break; // PUT、DELETE等其他方法可以按照同样的逻辑扩展 default: throw new IllegalArgumentException("Unsupported HTTP method: " + wrappedRequest.getMethod()); } // 复制所有请求头(自动处理多值头的情况) wrappedRequest.getHeaders().forEach((headerName, headerValues) -> { headerValues.forEach(value -> apacheRequest.addHeader(headerName, value)); }); return apacheRequest; }
Spring的ServletServerHttpRequest已经帮你处理了请求头的多值问题、请求体的流读取等细节,比自己手动实现更可靠。
2. 轻量方案:结合Apache HttpClient和Commons IO
如果不想引入Spring这类重型框架,可以用Apache HttpClient本身结合Commons IO来简化转换,虽然需要写一点代码,但比完全从头写要省事:
先引入依赖:
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.14</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency>
转换代码示例:
import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ByteArrayEntity; import org.apache.commons.io.IOUtils; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.Enumeration; public org.apache.http.HttpRequest convertToApacheHttpRequest(HttpServletRequest servletRequest) throws IOException { HttpUriRequest apacheRequest; String method = servletRequest.getMethod(); String uri = servletRequest.getRequestURL().toString(); // 创建对应HTTP方法的请求实例 switch (method) { case "GET": apacheRequest = new HttpGet(uri); break; case "POST": apacheRequest = new HttpPost(uri); // 读取并设置请求体 byte[] body = IOUtils.toByteArray(servletRequest.getInputStream()); ((HttpPost) apacheRequest).setEntity(new ByteArrayEntity(body)); break; // 其他方法自行扩展 default: throw new IllegalArgumentException("Unsupported method: " + method); } // 复制所有请求头 Enumeration<String> headerNames = servletRequest.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); Enumeration<String> headerValues = servletRequest.getHeaders(headerName); while (headerValues.hasMoreElements()) { apacheRequest.addHeader(headerName, headerValues.nextElement()); } } return apacheRequest; }
关键注意事项
- 请求体只能读取一次:
HttpServletRequest的输入流默认只能读一次,如果你的代码在转换之前已经读取过流,需要先把请求体缓存起来(比如用ContentCachingRequestWrapper),否则转换时会读不到内容。 - HTTP方法全覆盖:要确保所有你业务中用到的HTTP方法(GET、POST、PUT、DELETE等)都有对应的Apache HttpRequest实现类。
内容的提问来源于stack exchange,提问作者Aravind
相关产品推荐
相关产品推荐

