使用Netty实现HttpServer
package netty; 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.HttpResponseStatus.OK; import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; import static org.jboss.netty.handler.codec.http.HttpHeaders.Values.KEEP_ALIVE; import com.alibaba.fastjson.JSON; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.HttpServerExpectContinueHandler; import io.netty.handler.codec.http.HttpUtil; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslHandler; import java.io.FileInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import lombok.Cleanup; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; /** * Test * * @author xfyou */ public class Test { @SneakyThrows public static void main(String[] args) { HttpServer server = new HttpServer(8080); server.start(); } @RequiredArgsConstructor private static class HttpServer { private final Integer port; @SneakyThrows public void start() { EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(20); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializerImpl()); ChannelFuture future = serverBootstrap.bind(port).sync(); System.out.println("Server started..."); future.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } } private static final class ChannelInitializerImpl extends ChannelInitializer<Channel> { private final SslContext sslContext; @SneakyThrows public ChannelInitializerImpl() { sslContext = createSslContext(); } @SneakyThrows private SslContext createSslContext() { String keyStoreFilePath = "/root/.ssl/test.pkcs12"; String keyStorePassword = "passwd"; KeyStore keyStore = KeyStore.getInstance("PKCS12"); @Cleanup InputStream inputStream = new FileInputStream(keyStoreFilePath); keyStore.load(inputStream, keyStorePassword.toCharArray()); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, keyStorePassword.toCharArray()); return SslContextBuilder.forServer(keyManagerFactory).build(); } @Override protected void initChannel(Channel ch) { ChannelPipeline cp = ch.pipeline(); // support SSL/TLS cp.addLast(new SslHandler(sslContext.newEngine(ch.alloc()))); // decode and encode cp.addLast(new HttpServerCodec()); // handle message-body of POST cp.addLast(new HttpObjectAggregator(Integer.MAX_VALUE)); cp.addLast(new HttpServerExpectContinueHandler()); cp.addLast(new SimpleChannelInboundHandler<FullHttpRequest>() { @Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) { System.out.println(msg.content().toString(StandardCharsets.UTF_8)); System.out.println(ch); String res = "I am OK"; FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(JSON.toJSONString(res).getBytes(StandardCharsets.UTF_8))); response.headers().set(CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); if (HttpUtil.isKeepAlive(msg)) { response.headers().set(CONNECTION, KEEP_ALIVE); ctx.writeAndFlush(response); } else { ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } ctx.flush(); } }); } } }