Skip to content

Commit e4e8be2

Browse files
committed
add 第5节课作业实践 1)整合httpclient和okhttp
update httpclient和okhttp的方法细节
1 parent 01d9794 commit e4e8be2

File tree

5 files changed

+225
-4
lines changed

5 files changed

+225
-4
lines changed

02nio/nio02/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@
5252
<artifactId>httpasyncclient</artifactId>
5353
<version>4.1.4</version>
5454
</dependency>
55+
56+
<dependency>
57+
<groupId>com.squareup.okhttp3</groupId>
58+
<artifactId>okhttp</artifactId>
59+
<version>3.10.0</version>
60+
</dependency>
5561

5662
<!--
5763
<dependency>

02nio/nio02/src/main/java/io/github/kimmking/gateway/NettyServerApplication.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public class NettyServerApplication {
99
public final static String GATEWAY_VERSION = "1.0.0";
1010

1111
public static void main(String[] args) {
12-
String proxyServer = System.getProperty("proxyServer","http://localhost:8088");
12+
String proxyServer = System.getProperty("proxyServer","http://localhost:8188");
1313
String proxyPort = System.getProperty("proxyPort","8888");
1414

1515
// http://localhost:8888/api/hello ==> gateway API

02nio/nio02/src/main/java/io/github/kimmking/gateway/inbound/HttpInboundHandler.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package io.github.kimmking.gateway.inbound;
22

3+
import io.github.kimmking.gateway.outbound.httpclient.HttpClientOutboundHandler;
34
import io.github.kimmking.gateway.outbound.httpclient4.HttpOutboundHandler;
5+
import io.github.kimmking.gateway.outbound.okhttp.OkhttpOutboundHandler;
46
import io.netty.channel.ChannelHandlerContext;
57
import io.netty.channel.ChannelInboundHandlerAdapter;
68
import io.netty.handler.codec.http.FullHttpRequest;
@@ -12,11 +14,15 @@ public class HttpInboundHandler extends ChannelInboundHandlerAdapter {
1214

1315
private static Logger logger = LoggerFactory.getLogger(HttpInboundHandler.class);
1416
private final String proxyServer;
15-
private HttpOutboundHandler handler;
16-
17+
private OkhttpOutboundHandler handler;
18+
// private HttpClientOutboundHandler handler;
19+
// private HttpOutboundHandler handler;
20+
1721
public HttpInboundHandler(String proxyServer) {
1822
this.proxyServer = proxyServer;
19-
handler = new HttpOutboundHandler(this.proxyServer);
23+
// handler = new HttpOutboundHandler(this.proxyServer);
24+
// handler = new HttpClientOutboundHandler(this.proxyServer);
25+
handler = new OkhttpOutboundHandler(this.proxyServer);
2026
}
2127

2228
@Override
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package io.github.kimmking.gateway.outbound.httpclient;
2+
3+
import io.netty.buffer.Unpooled;
4+
import io.netty.channel.ChannelFutureListener;
5+
import io.netty.channel.ChannelHandlerContext;
6+
import io.netty.handler.codec.http.DefaultFullHttpResponse;
7+
import io.netty.handler.codec.http.FullHttpRequest;
8+
import io.netty.handler.codec.http.FullHttpResponse;
9+
import io.netty.handler.codec.http.HttpUtil;
10+
import org.apache.http.HttpResponse;
11+
import org.apache.http.client.ClientProtocolException;
12+
import org.apache.http.client.ResponseHandler;
13+
import org.apache.http.client.methods.CloseableHttpResponse;
14+
import org.apache.http.client.methods.HttpGet;
15+
import org.apache.http.concurrent.FutureCallback;
16+
import org.apache.http.impl.client.CloseableHttpClient;
17+
import org.apache.http.impl.client.HttpClients;
18+
import org.apache.http.protocol.HTTP;
19+
import org.apache.http.util.EntityUtils;
20+
21+
import java.io.IOException;
22+
23+
import static io.netty.handler.codec.http.HttpResponseStatus.NO_CONTENT;
24+
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
25+
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
26+
27+
public class HttpClientOutboundHandler {
28+
29+
private CloseableHttpClient httpClient;
30+
private String backendUrl;
31+
32+
//
33+
public HttpClientOutboundHandler(String backendUrl) {
34+
35+
this.backendUrl = backendUrl.endsWith("/") ? backendUrl.substring(0, backendUrl.length() - 1) : backendUrl;
36+
httpClient = HttpClients.createDefault();
37+
}
38+
39+
//
40+
public void handle(FullHttpRequest fullRequest, ChannelHandlerContext ctx) {
41+
42+
final String url = this.backendUrl + fullRequest.uri();
43+
doHttpGet(fullRequest, ctx, url);
44+
}
45+
46+
private void doHttpGet(FullHttpRequest inbound, ChannelHandlerContext ctx, String url) {
47+
48+
HttpGet httpGet = new HttpGet(url);
49+
//httpGet.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
50+
httpGet.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE);
51+
52+
try {
53+
54+
//
55+
// handleEndResponse(inbound, ctx, httpClient.execute(httpGet));
56+
57+
httpClient.execute(httpGet, new ResponseHandler<Object>() {
58+
@Override
59+
public Object handleResponse(HttpResponse endpointResponse) throws ClientProtocolException, IOException {
60+
61+
return handleEndResponse(inbound, ctx, endpointResponse);
62+
}
63+
});
64+
65+
} catch (IOException e) {
66+
e.printStackTrace();
67+
}
68+
}
69+
70+
private Object handleEndResponse(FullHttpRequest fullRequest, ChannelHandlerContext ctx, HttpResponse endpointResponse) {
71+
72+
FullHttpResponse response = null;
73+
try {
74+
75+
byte[] body = EntityUtils.toByteArray(endpointResponse.getEntity());
76+
77+
78+
// body = EntityUtils.toString(endpointResponse.getEntity()).getBytes();
79+
80+
response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(body));
81+
response.headers().set("Content-Type", "application/json");
82+
response.headers().setInt("Content-Length", Integer.parseInt(endpointResponse.getFirstHeader("Content-Length").getValue()));
83+
} catch (Exception e) {
84+
e.printStackTrace();
85+
response = new DefaultFullHttpResponse(HTTP_1_1, NO_CONTENT);
86+
exceptionCaught(ctx, e);
87+
} finally {
88+
if (fullRequest != null) {
89+
if (!HttpUtil.isKeepAlive(fullRequest)) {
90+
ctx.write(response).addListener(ChannelFutureListener.CLOSE);
91+
} else {
92+
//response.headers().set(CONNECTION, KEEP_ALIVE);
93+
ctx.write(response);
94+
}
95+
}
96+
ctx.flush();
97+
//ctx.close();
98+
}
99+
100+
return null;
101+
}
102+
103+
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
104+
cause.printStackTrace();
105+
ctx.close();
106+
}
107+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,106 @@
11
package io.github.kimmking.gateway.outbound.okhttp;
22

3+
import io.netty.buffer.Unpooled;
4+
import io.netty.channel.ChannelFutureListener;
5+
import io.netty.channel.ChannelHandlerContext;
6+
import io.netty.handler.codec.http.DefaultFullHttpResponse;
7+
import io.netty.handler.codec.http.FullHttpRequest;
8+
import io.netty.handler.codec.http.FullHttpResponse;
9+
import io.netty.handler.codec.http.HttpUtil;
10+
import okhttp3.*;
11+
import org.apache.http.protocol.HTTP;
12+
import org.apache.http.util.EntityUtils;
13+
14+
import java.io.IOException;
15+
import java.net.SocketTimeoutException;
16+
import java.util.concurrent.TimeUnit;
17+
18+
import static io.netty.handler.codec.http.HttpResponseStatus.NO_CONTENT;
19+
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
20+
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
21+
322
public class OkhttpOutboundHandler {
23+
24+
private String backendUrl;
25+
private OkHttpClient httpClient;
26+
27+
private final static int READ_TIMEOUT = 20;
28+
29+
private final static int CONNECT_TIMEOUT = 10;
30+
31+
private final static int WRITE_TIMEOUT = 60;
32+
33+
34+
public OkhttpOutboundHandler(String backendUrl) {
35+
36+
this.backendUrl = backendUrl.endsWith("/") ? backendUrl.substring(0, backendUrl.length() - 1) : backendUrl;
37+
httpClient = new OkHttpClient.Builder()
38+
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
39+
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
40+
.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
41+
.build();
42+
}
43+
44+
public void handle(FullHttpRequest fullRequest, ChannelHandlerContext ctx) {
45+
46+
String url = this.backendUrl + fullRequest.uri();
47+
doOkHttpGet(fullRequest, ctx, url);
48+
}
49+
50+
private void doOkHttpGet(FullHttpRequest inbound, ChannelHandlerContext ctx, String url) {
51+
52+
53+
httpClient.newCall(new Request.Builder().url(url).addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE).build()).enqueue(new Callback() {
54+
@Override
55+
public void onFailure(Call call, IOException e) {
56+
57+
if (e.getCause().equals(SocketTimeoutException.class)) {
58+
59+
// 处理省略
60+
// 比如可以加重试逻辑
61+
}
62+
}
63+
64+
@Override
65+
public void onResponse(Call call, Response response) throws IOException {
66+
67+
handleResponse(inbound, ctx, response);
68+
}
69+
});
70+
}
71+
72+
private void handleResponse(FullHttpRequest fullRequest, ChannelHandlerContext ctx, Response response) {
73+
74+
FullHttpResponse fullHttpResponse = null;
75+
try {
76+
77+
byte[] body = response.body().bytes();
78+
79+
fullHttpResponse = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(body));
80+
fullHttpResponse.headers().set("Content-Type", "application/json");
81+
fullHttpResponse.headers().setInt("Content-Length", Integer.parseInt(response.header("Content-Length")));
82+
83+
} catch (Exception e) {
84+
e.printStackTrace();
85+
fullHttpResponse = new DefaultFullHttpResponse(HTTP_1_1, NO_CONTENT);
86+
exceptionCaught(ctx, e);
87+
} finally {
88+
if (fullRequest != null) {
89+
if (!HttpUtil.isKeepAlive(fullRequest)) {
90+
ctx.write(fullHttpResponse).addListener(ChannelFutureListener.CLOSE);
91+
} else {
92+
//response.headers().set(CONNECTION, KEEP_ALIVE);
93+
ctx.write(fullHttpResponse);
94+
}
95+
}
96+
ctx.flush();
97+
//ctx.close();
98+
}
99+
100+
}
101+
102+
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
103+
cause.printStackTrace();
104+
ctx.close();
105+
}
4106
}

0 commit comments

Comments
 (0)