httpClient请求转发个人理解

最近有个项目需要做一个请求转发的功能场景如下:

公司A 、公司B(本公司)、公司C、公司D

A访问B、B从C和D中拿数据,

A访问B的时候有个一下三种情况

1、get方式

2、post方式参数格式form-data

3、post方式参数格式json

get方式解决代码

public static void httpGet(String apiReal, HttpServletRequest request, HttpServletResponse response,
List<NameValuePair> additionalMap) throws UnsupportedEncodingException, URISyntaxException, UnknownHostException {
CloseableHttpClient httpClient = SSLUtils.createSSLClientDefault();

URIBuilder uriBuilder = new URIBuilder(apiReal);
//普通参数赋值
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String parameterName = parameterNames.nextElement();
for (String value : request.getParameterValues(parameterName)) {
if (value != null && !"null".equals(value)) {
BasicNameValuePair bNVP = new BasicNameValuePair(parameterName, value);
additionalMap.add(bNVP);
}
}
}

uriBuilder.setParameters(additionalMap);
//创建HttpGet对象,设置URL地址
HttpGet httpGet = new HttpGet(uriBuilder.build());
//请求头参数赋值
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
if (!"host".equalsIgnoreCase(headerName)) {
httpGet.addHeader(headerName, request.getHeader(headerName));
}
}

HttpResponse httpResponse = null;
try {
//发送请求
httpResponse = httpClient.execute(httpGet);
if (httpResponse != null) {
HttpEntity responseEntity = httpResponse.getEntity();
if (responseEntity != null) {
// httpResponse 请求结果赋值给 response
responseEntity.writeTo(response.getOutputStream());
}
}
} catch (IOException e) {
e.printStackTrace();
}
if (httpResponse != null) {
response.setStatus(httpResponse.getStatusLine().getStatusCode());
HeaderIterator headerIterator = httpResponse.headerIterator();
while (headerIterator.hasNext()) {
Header header = headerIterator.nextHeader();
if ("Content-Type".equals(header.getName())) {
response.setHeader(header.getName(), header.getValue());
}
}
}
}

post方式参数格式form-data:

public static void httpPost(String apiReal, HttpServletRequest request, HttpServletResponse response,
List<NameValuePair> additionalMap) {
CloseableHttpClient httpClient = SSLUtils.createSSLClientDefault();
HttpPost httpPost = new HttpPost(apiReal);

Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
if (!(headerName.equalsIgnoreCase("host") || headerName.equalsIgnoreCase("content-length"))) {
httpPost.addHeader(headerName, request.getHeader(headerName));
}
}

List<NameValuePair> params = new ArrayList<NameValuePair>();
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String parameterName = parameterNames.nextElement();
for (String value : request.getParameterValues(parameterName)) {
if (value != null && !value.equals("null")) params.add(new BasicNameValuePair(parameterName, value));
}
}

HttpResponse httpResponse = null;
try {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
httpPost.setEntity(entity);
httpResponse = httpClient.execute(httpPost);
if (httpResponse != null) {
HttpEntity responseEntity = httpResponse.getEntity();
if (responseEntity != null) {
log.info(responseEntity.toString());
responseEntity.writeTo(response.getOutputStream());
}
}
} catch (IOException e) {
e.printStackTrace();
}
if (httpResponse != null) {
response.setStatus(httpResponse.getStatusLine().getStatusCode());
HeaderIterator headerIterator = httpResponse.headerIterator();
while (headerIterator.hasNext()) {
Header header = headerIterator.nextHeader();
if (header.getName().equals("Content-Type")) {
response.setHeader(header.getName(), header.getValue());
}
}

}
}

post方式参数格式json:

json格式会有一个问题,json存放在request流中,request的流只能读取一边(默认情况),第二次读取会出现流为空的问题,所以就要解决流不能重复获取,

我在网上找了个博客https://www.cnblogs.com/panchanggui/p/12297860.html通过HttpServletRequestWrapper解决,流数据可以重复获取之后就可以通过下列代码写到新的请求里

  //bodyParam是流
StringEntity bodyData = new StringEntity(bodyParam, "UTF-8"); httpPost.setEntity(bodyData);

如何获取流文件?

   public static JSONObject getJsonObjectByRequest(HttpServletRequest request) {
        StringBuffer sb = new StringBuffer();
        String line = null;
        try {
            BufferedReader reader = request.getReader();
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (Exception e) { /*report an error*/ }
        String jsonString = sb.toString().replaceAll("\s", "").replaceAll("
", "");
        JSONObject jsonObject = JSON.parseObject(jsonString);
        return jsonObject;
    }

通用工具类:


import org.apache.http.HttpResponse;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;

import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class SSLUtils {

public static CloseableHttpClient createSSLClientDefault() {

ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
return 5 * 1000;
}

};

try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
//信任所有
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
return HttpClients.custom()
.setConnectionManagerShared(true)
.setSSLSocketFactory(sslsf)
.setKeepAliveStrategy(myStrategy)
.evictExpiredConnections()
.build();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
return HttpClients.createDefault();
}

}
原文地址:https://www.cnblogs.com/lovetl/p/14251041.html