|
@@ -14,19 +14,20 @@ import io.netty.buffer.ByteBuf;
|
|
|
import io.netty.buffer.Unpooled;
|
|
|
import io.netty.channel.ChannelFutureListener;
|
|
|
import io.netty.channel.ChannelHandlerContext;
|
|
|
-import io.netty.channel.SimpleChannelInboundHandler;
|
|
|
+import io.netty.channel.ChannelInboundHandlerAdapter;
|
|
|
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
|
|
import io.netty.handler.codec.http.FullHttpResponse;
|
|
|
import io.netty.handler.codec.http.HttpHeaderNames;
|
|
|
-import io.netty.handler.codec.http.HttpHeaders;
|
|
|
import io.netty.handler.codec.http.HttpRequest;
|
|
|
-import io.netty.handler.codec.http.HttpResponseStatus;
|
|
|
-import io.netty.handler.codec.http.HttpVersion;
|
|
|
import io.netty.util.AsciiString;
|
|
|
import io.netty.util.CharsetUtil;
|
|
|
+import io.netty.util.ReferenceCountUtil;
|
|
|
import io.netty.util.concurrent.FastThreadLocal;
|
|
|
|
|
|
-public class HelloServerHandler extends SimpleChannelInboundHandler<HttpRequest> {
|
|
|
+import static io.netty.handler.codec.http.HttpResponseStatus.*;
|
|
|
+import static io.netty.handler.codec.http.HttpVersion.*;
|
|
|
+
|
|
|
+public class HelloServerHandler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
|
private static final FastThreadLocal<DateFormat> FORMAT = new FastThreadLocal<DateFormat>() {
|
|
|
@Override
|
|
@@ -35,17 +36,17 @@ public class HelloServerHandler extends SimpleChannelInboundHandler<HttpRequest>
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- private static final ObjectMapper newMapper() {
|
|
|
+ private static ObjectMapper newMapper() {
|
|
|
ObjectMapper m = new ObjectMapper();
|
|
|
m.registerModule(new AfterburnerModule());
|
|
|
return m;
|
|
|
}
|
|
|
|
|
|
- private static final Message newMsg() {
|
|
|
+ private static Message newMsg() {
|
|
|
return new Message("Hello, World!");
|
|
|
}
|
|
|
|
|
|
- private static final int jsonLen() {
|
|
|
+ private static int jsonLen() {
|
|
|
try {
|
|
|
return newMapper().writeValueAsBytes(newMsg()).length;
|
|
|
} catch (JsonProcessingException e) {
|
|
@@ -83,34 +84,50 @@ public class HelloServerHandler extends SimpleChannelInboundHandler<HttpRequest>
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) throws Exception {
|
|
|
- HttpRequest request = (HttpRequest) msg;
|
|
|
+ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
|
|
+ if (msg instanceof HttpRequest) {
|
|
|
+ try {
|
|
|
+ HttpRequest request = (HttpRequest) msg;
|
|
|
+ process(ctx, request);
|
|
|
+ } finally {
|
|
|
+ ReferenceCountUtil.release(msg);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ ctx.fireChannelRead(msg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void process(ChannelHandlerContext ctx, HttpRequest request) throws Exception {
|
|
|
String uri = request.uri();
|
|
|
switch (uri) {
|
|
|
- case "/plaintext":
|
|
|
- writeResponse(ctx, request, PLAINTEXT_CONTENT_BUFFER.duplicate(), TYPE_PLAIN, PLAINTEXT_CLHEADER_VALUE);
|
|
|
- return;
|
|
|
- case "/json":
|
|
|
- byte[] json = MAPPER.writeValueAsBytes(newMsg());
|
|
|
- writeResponse(ctx, request, Unpooled.wrappedBuffer(json), TYPE_JSON, JSON_CLHEADER_VALUE);
|
|
|
- return;
|
|
|
+ case "/plaintext":
|
|
|
+ writePlainResponse(ctx, PLAINTEXT_CONTENT_BUFFER.duplicate());
|
|
|
+ return;
|
|
|
+ case "/json":
|
|
|
+ byte[] json = MAPPER.writeValueAsBytes(newMsg());
|
|
|
+ writeJsonResponse(ctx, Unpooled.wrappedBuffer(json));
|
|
|
+ return;
|
|
|
}
|
|
|
- FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND, Unpooled.EMPTY_BUFFER, false);
|
|
|
+ FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND, Unpooled.EMPTY_BUFFER, false);
|
|
|
ctx.write(response).addListener(ChannelFutureListener.CLOSE);
|
|
|
}
|
|
|
|
|
|
- private void writeResponse(ChannelHandlerContext ctx, HttpRequest request, ByteBuf buf, CharSequence contentType, CharSequence contentLength) {
|
|
|
+ private void writePlainResponse(ChannelHandlerContext ctx, ByteBuf buf) {
|
|
|
+ ctx.write(makeResponse(buf, TYPE_PLAIN, PLAINTEXT_CLHEADER_VALUE), ctx.voidPromise());
|
|
|
+ }
|
|
|
|
|
|
- // Build the response object.
|
|
|
- FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf, false);
|
|
|
- HttpHeaders headers = response.headers();
|
|
|
- headers.set(CONTENT_TYPE_ENTITY, contentType);
|
|
|
- headers.set(SERVER_ENTITY, SERVER_NAME);
|
|
|
- headers.set(DATE_ENTITY, date);
|
|
|
- headers.set(CONTENT_LENGTH_ENTITY, contentLength);
|
|
|
+ private void writeJsonResponse(ChannelHandlerContext ctx, ByteBuf buf) {
|
|
|
+ ctx.write(makeResponse(buf, TYPE_JSON, JSON_CLHEADER_VALUE), ctx.voidPromise());
|
|
|
+ }
|
|
|
|
|
|
- // Close the non-keep-alive connection after the write operation is done.
|
|
|
- ctx.write(response, ctx.voidPromise());
|
|
|
+ private FullHttpResponse makeResponse(ByteBuf buf, CharSequence contentType, CharSequence contentLength) {
|
|
|
+ final FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, buf, false);
|
|
|
+ response.headers()
|
|
|
+ .set(CONTENT_TYPE_ENTITY, contentType)
|
|
|
+ .set(SERVER_ENTITY, SERVER_NAME)
|
|
|
+ .set(DATE_ENTITY, date)
|
|
|
+ .set(CONTENT_LENGTH_ENTITY, contentLength);
|
|
|
+ return response;
|
|
|
}
|
|
|
|
|
|
@Override
|