httpclient请求转发实战
代码需求
公司有eureka管理页面、spring admin管理页面、kafka管理页面、日志查询页面和文件系统查询页面,现在要将这些页面放到一个统一的网页中管理,通过标签分别跳转到不同的页面,省去了分别点开的麻烦
这些单个的系统外网访问不到,但是我这个系统(manage)能够被外网访问,需要在后台做请求转发功能:
- 1 manage前台发送请求给后台
- 2 manage后台拿到传过来的参数和请求地址,使用httpclient请求内网eureka等
- 3 将返回的数据返回到前台
依赖地址
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
httpclient连接池
/**
* http连接池配置
* @author piper
* @date 2018/7/4 13:15
*/
@Configuration
public class ConnectionManager {
// 最大连接数
private static final int MAX_TOTAL = 200;
// 每一个路由的最大连接数
private static final int MAX_PER_ROUTE = 500;
//从连接池中获得连接的超时时间
private static final int CONNECTION_REQUEST_TIMEOUT = 3000;
//连接超时
private static final int CONNECTION_TIMEOUT = 3000;
//获取数据的超时时间
private static final int SOCKET_TIMEOUT = 5000;
private PoolingHttpClientConnectionManager cm;
private CloseableHttpClient httpClient;
/**
* 重连接策略
*/
HttpRequestRetryHandler retryHandler = (IOException exception, int executionCount, HttpContext context) -> {
if (executionCount >= 3) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof InterruptedIOException) {
// Timeout
return false;
}
if (exception instanceof UnknownHostException) {
// Unknown host
return false;
}
if (exception instanceof ConnectTimeoutException) {
// Connection refused
return false;
}
if (exception instanceof SSLException) {
// SSL handshake exception
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// Retry if the request is considered idempotent
return true;
}
return false;
};
/**
* 配置连接参数
*/
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
.setConnectTimeout(CONNECTION_TIMEOUT)
.setSocketTimeout(SOCKET_TIMEOUT)
.build();
public ConnectionManager() {
cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(MAX_TOTAL);
cm.setDefaultMaxPerRoute(MAX_PER_ROUTE);
// 定制实现HttpClient,全局只有一个HttpClient
httpClient = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(requestConfig)
.setRetryHandler(retryHandler)
.build();
}
@Bean
public CloseableHttpClient getHttpClient() {
return httpClient;
}
}
一次请求的流程(请予以重视)
- 1 创建HttpPost或HttpGet方法
- 2 将请求参数放入方法内
- 3 设置方法的请求头,比如:Content-Type(这个尽量带上)
- 4 httpclient对象拿着HttpPost去请求
- 5 返回CloseableHttpResponse对象,数据都在这里了,仔细观察
入门demo
try {
HttpClient client = HttpClients.createDefault(); //client对象
HttpGet get = new HttpGet("http://localhost:8080/test"); //创建get请求
CloseableHttpResponse response = client.execute(get); //执行get请求
String mes = EntityUtils.toString(response.getEntity()); //将返回体的信息转换为字符串
System.out.println(mes);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
如何处理前台传入的参数
烦请移步 https://blog.csdn.net/GY325416/article/details/81413177
如何处理返回数据
参考另一篇博客 https://blog.csdn.net/GY325416/article/details/81436078