1. HttpServer
HttpServer作为http服务器的server端:
public final class HttpServer { private static final String IP = "127.0.0.1"; private static final int PORT = 9000; private static final int BIZ_THREAD_SIZE = 100; private static final Logger logger = LoggerFactory.getLogger(HttpServer.class); public static void main(String[] args) throws Exception { System.out.println("启动Server..."); HttpServer.start(); } public static void start() throws Exception { initServerConfig(); // new NioEventLoopGroup()默认线程数为CPU核心数的两倍(Runtime.getRuntime().availableProcessors() * 2),所以这里不用额外指定。 EventLoopGroup bossGroup = new NioEventLoopGroup(); // 这里worker不能使用默认,如果并发大的话需要增加线程数量 EventLoopGroup workerGroup = new NioEventLoopGroup(BIZ_THREAD_SIZE); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) // ChannelOption.SO_BACKLOG对应的是tcp/ip协议listen函数中的backlog参数。函数listen(int socketfd, int backlog)用来初始化服务端可连接队列。 // 服务端处理客户端连接请求是顺序处理的,所以同一时间只能处理一个客户端连接,多个客户端来的时候,服务端将不能处理的客户端连接请求放在队列中等待处理,backlog参数指定了队列的大小。 .option(ChannelOption.SO_BACKLOG, 1024) .handler(new LoggingHandler(LogLevel.INFO)) .childOption(ChannelOption.SO_KEEPALIVE, true) // 子channel配置,保持长连接 .childHandler(new HttpServerInitializer()); // sync追踪代码可以得到:this.await(),实现阻塞 ChannelFuture channelFuture = bootstrap.bind(IP, PORT).sync(); // 启动失败则关闭线程组 if (!channelFuture.isSuccess()) { shutdown(bossGroup, workerGroup); throw new RuntimeException(channelFuture.cause()); } channelFuture.channel().closeFuture().sync(); logger.info("bootstrap channel closed..."); } finally { shutdown(bossGroup, workerGroup); } } // 添加路径映射和过滤器映射 private static void initServerConfig() { ServerContext.setFilter(ServerContext.MAPPING_ALL, Filter.class); ServerContext.setFilter("/template", TemplateFilter.class); ServerContext.setAction(ServerContext.MAPPING_ALL, DefaultIndexAction.class); ServerContext.setAction("/template", TemplateAction.class); ServerContext.setAction("/files", FileAction.class); ServerContext.setROOT("root"); ServerContext.setPORT(8090); } private static void shutdown(EventLoopGroup bossGroup, EventLoopGroup workerGroup) { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); }}HttpServerInitializer设置http编解码器,以及请求aggregator等:
public class HttpServerInitializer extends ChannelInitializer<SocketChannel> { @Override public void initChannel(SocketChannel socketChannel) { ChannelPipeline pipeline = socketChannel.pipeline(); pipeline //或者使用HttpRequestDecoder & HttpResponseEncoder .addLast(new HttpServerCodec()) //把Http Aggregator放入管道里。Http Aggregator会把多个消息转换为一个单一的FullHttpRequest或是FullHttpResponse .addLast(new Http Aggregator(1024 * 1024)) //压缩Http消息// .addLast(new HttpChunkContentCompressor()) //大文件支持,文件上传时使用// .addLast(new ChunkedWriteHandler()) .addLast(new HttpServerExpectContinueHandler()) .addLast(new HttpServerDispatcherHandler()); }}入栈处理器,用于转发http请求,类似于DispatcherServlet:
public class HttpServerDispatcherHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, msg) { if (!(msg instanceof FullHttpRequest)) { return; } FullHttpRequest fullHttpRequest = (FullHttpRequest) msg; final Request customerRequest = Request.build(ctx, fullHttpRequest); final Response customerResponse = Response.build(ctx, customerRequest); if (customerRequest.getRequestUrl().equals(HttpHelper.FAVICON_ICO)) { return; } // 过滤器放行之后,执行action,实际处理业务逻辑 boolean passFilter = doFilter(customerRequest, customerResponse); if (passFilter) { doAction(customerRequest, customerResponse); } //如果发送请求未被触发,则触发之,否则跳过。 if(false == customerResponse.isSent()) { customerResponse.response(); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } @Override public void channelReadComplete(ChannelHandlerContext ctx) { ctx.flush(); } /** * 过滤器 * @param request * @param response * @return */ private boolean doFilter(Request request, Response response) { //全局过滤器 Filter filter = ServerContext.getFilter(ServerContext.MAPPING_ALL); if(null != filter) { if(false == filter.doFilter(request, response)) { return false; } } //自定义过滤器 filter = ServerContext.getFilter(request.getRequestUrl()); if(null != filter) { if(false == filter.doFilter(request, response)) { return false; } } return true; } /** * 请求处理器 * 相当于servlet * @param request * @param response */ private void doAction(Request request, Response response) { Action action = ServerContext.getAction(request.getRequestUrl()); if (null == action) { //查找匹配所有路径的Action action = ServerContext.getAction(ServerContext.MAPPING_ALL); if(null == action) { // 非Action方法,调用静态文件读取 action = Singleton.get(FileAction.class); } } action.doAction(request, response); }}过滤器
public interface Filter { /** * 执行过滤 * @param request 请求对象 * @param response 响应对象 * @return 如果返回true,则继续执行下一步内容,否则中断 */ boolean doFilter(Request request, Response response);}过滤器示例:
public class TemplateFilter implements Filter { @Override public boolean doFilter(Request request, Response response) { System.out.println("welcome in template filter..."); return true; }}action
action用于实际处理业务,顶层接口:
public interface Action { void doAction(Request request, Response response);}抽象Adapter:
public abstract class AbstractAction implements Action { @Override public void doAction(Request request, Response response) { String method = request.getMethod(); if (HttpHelper.METHOD_GET.equals(method)) { doGet(request, response); } else if (HttpHelper.METHOD_POST.equals(method)) { doPost(request, response); } else if (HttpHelper.METHOD_PUT.equals(method)) { doPut(request, response); } else if (HttpHelper.METHOD_DELETE.equals(method)) { doDelete(request, response); } else if (HttpHelper.METHOD_HEAD.equals(method)) { doHead(request, response); } else if (HttpHelper.METHOD_OPTIONS.equals(method)) { doOptions(request, response); } else if (HttpHelper.METHOD_TRACE.equals(method)) { doTrace(request, response); } } protected void doGet(Request request, Response response) {} protected void doPost(Request request, Response response) {} protected void doPut(Request request, Response response) {} protected void doDelete(Request request, Response response) {} protected void doOptions(Request request, Response response) {} protected void doHead(Request request, Response response) {} protected void doTrace(Request request, Response response) {}}action示例:
public class TemplateAction extends AbstractAction { @Override protected void doGet(Request request, Response response) { response.setContentType(HttpHelper.CONTENT_TYPE_JSON); response.setContent("welcome in template action, do get..."); } @Override protected void doPost(Request request, Response response) { response.setContent("welcome in template action, do post..."); }}。。。
继续阅读与本文标签相同的文章
上一篇 :
Java开发数据库设计的14个技巧,你知道几个?
-
重新认识一个强大的 Gson
2026-05-16栏目: 教程
-
全文搜索引擎选ElasticSearch还是Solr?
2026-05-16栏目: 教程
-
如何实现一个权限管理系统?
2026-05-16栏目: 教程
-
常用的设计模式汇总,超详细!
2026-05-16栏目: 教程
-
Spring IoC、AOP、Transaction、MVC 归纳小结
2026-05-16栏目: 教程
