Java tutorial
/* * Copyright 2016 Dennis Hu * * Dennis Hu licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package cn.dennishucd.nettyhttpserver; import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION; import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH; import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE; import static io.netty.handler.codec.http.HttpHeaderNames.KEEP_ALIVE; import static io.netty.handler.codec.http.HttpResponseStatus.CONTINUE; import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND; import static io.netty.handler.codec.http.HttpResponseStatus.OK; import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; 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.HttpContent; import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpUtil; import io.netty.util.CharsetUtil; import org.apache.log4j.Logger; import cn.dennishucd.utils.CTools; public class HttpServerHandler extends ChannelInboundHandlerAdapter { private Logger logger = Logger.getLogger(this.getClass()); private static final String CONTENT = "{\"code\":2000,\"msg\":\"?\"}"; private static final String URL = "/rest/push/token"; private HttpRequest request; @SuppressWarnings("deprecation") @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { if (msg instanceof HttpRequest) { request = (HttpRequest) msg; if (HttpUtil.is100ContinueExpected(request)) { ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); } if (!request.uri().equalsIgnoreCase(URL)) { sendError(ctx, NOT_FOUND); return; } } if (msg instanceof HttpContent) { HttpContent content = (HttpContent) msg; ByteBuf buf = content.content(); UserToken ut = CTools.JSONStr2Object(buf.toString(io.netty.util.CharsetUtil.UTF_8), UserToken.class); logger.info("request body: " + buf.toString(io.netty.util.CharsetUtil.UTF_8)); buf.release(); boolean keepAlive = HttpUtil.isKeepAlive(request); FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(CONTENT.getBytes())); response.headers().set(CONTENT_TYPE, "application/json"); response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes()); logger.info("response body: " + CONTENT); if (!keepAlive) { ctx.write(response).addListener(ChannelFutureListener.CLOSE); } else { response.headers().set(CONNECTION, KEEP_ALIVE); ctx.write(response); } } else { ctx.fireChannelRead(msg); } } @Override public void channelReadComplete(ChannelHandlerContext ctx) { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, status, Unpooled.copiedBuffer("Failure: " + status + "\r\n", CharsetUtil.UTF_8)); response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8"); // Close the connection as soon as the error message is sent. ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } }