简单的设计思路就是,启动一个可以截断并处理Http请求的服务器代码。使用netty提供的boss线程与worker线程的模型,并使用netty的http解码器。自行编写了http url处理的部分。在接口层面,使用json作为格式。

  初始化扫描会指定扫描controller.container下的类,使用了自定义Annotation并且单例的方式加载,未考虑太多细节就为了好玩。

  接下来使用postman尝试调用接口。

  一个简单的netty搭建的web服务就完成了。

package server;

import handler.HttpServerHandler;
import initScan.InitialProcess;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpServerCodec; /**
* Created by MacBook on 2019/7/14.
*/
public class ServerStarter { private EventLoopGroup boss ; private EventLoopGroup worker ; private int port; private static int DEFAULT_PORT = 8080; public ServerStarter(){
boss = new NioEventLoopGroup();
worker = new NioEventLoopGroup();
port = DEFAULT_PORT;
} public ServerStarter(int port){
this();
if(port < 0 || port > 65535){
throw new IllegalArgumentException("port:"+port+" is illegal");
}
this.port = port;
} public void startup() throws InterruptedException{ if(boss.isShutdown() || worker.isShutdown()){
throw new IllegalStateException("server was closed");
} // 初始化容器
InitialProcess initialProcess = new InitialProcess();
initialProcess.init(); ServerBootstrap serverBootstrap = new ServerBootstrap();
System.out.println("=====http server start ");
serverBootstrap.channel(NioServerSocketChannel.class)
.group(boss,worker)
.childOption(ChannelOption.SO_KEEPALIVE,true)
.option(ChannelOption.SO_BACKLOG,1024)
.childHandler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("http-decode",new HttpServerCodec());
socketChannel.pipeline().addLast(new HttpServerHandler());
}
}); ChannelFuture future = serverBootstrap.bind(port).sync(); System.out.println("server port listen:"+port); future.channel().closeFuture().sync(); shutDownGracefully();
} /**
* 关闭管道
*/
public void shutDownGracefully(){
this.boss.shutdownGracefully();
this.worker.shutdownGracefully();
} }

  这是服务器启动的核心代码,首先初始化两个Nio线程组,把它们绑定到ServerBootstrap里,并添加Handler。

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import controller.Properties;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import response.BaseResponse; import java.lang.reflect.Method; /**
* Created by MacBook on 2019/7/14.
*/
public class HttpServerHandler extends ChannelInboundHandlerAdapter{ @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if(msg instanceof HttpRequest){
HttpRequest request = (HttpRequest)msg;
// boolean keepAlive = HttpUtil.isKeepAlive(request); System.out.println("http request method :"+request.method());
System.out.println("http request uri : "+request.uri()); Object controller = Properties.urlController.get(request.uri());
Method m = Properties.urlMethod.get(request.uri());
if(controller == null){
FullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND);
ctx.writeAndFlush(httpResponse).addListener(ChannelFutureListener.CLOSE); }else {
FullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json");
Object result = m.invoke(controller); httpResponse.content().writeBytes(JSON.toJSONString(result,SerializerFeature.WriteMapNullValue).getBytes()); ctx.writeAndFlush(httpResponse).addListener(ChannelFutureListener.CLOSE);
} }
}
}

  这是处理器的代码,在经过第一个Http解码器之后,进来的对象msg已经被转化为HttpRequest了。

最新文章

  1. haproxy para config
  2. MKRCVCD-MKRCVCDSER.exe can&#39;t start in service
  3. SQL查出异常数据(ORA-01722: 无效数字)
  4. java如何运行OS命令(转)
  5. 如何在Android中添加系统服务
  6. Ubuntu 18.04编译AOSP源码
  7. 剑指offer:调整数组顺序使奇数位于偶数前面
  8. 人脸识别1:n对比 (二)
  9. Sudoku(POJ2676/3074)
  10. Java 开源博客 Solo 1.9.0 发布 - 新皮肤
  11. 【转】说说MySQL中的Redo log Undo log都在干啥
  12. Nginx自学笔记
  13. 在Android工程中加入AIDL文件时,gen目录生成的文件报错-问题解决
  14. SQL思维导图
  15. Android微信支付SDK开发
  16. element ui 栅格布局
  17. Mistakes(Updating)
  18. eclipse里面的时间错误,比电脑系统时间慢了8个小时
  19. [BZOJ1901]Dynamic Rankings
  20. python 下载图片的方法

热门文章

  1. IDEA 2017 安装和破解
  2. nginx的负载均衡和反向代理
  3. 20190926 - macOS 下查看进程路径
  4. 论UT阶段重要性
  5. CentOS7安装openjdk8+环境变量配置
  6. Spring RestTemplate详解(转载)
  7. pubwin扫描安装
  8. NPM安装过程中的一些问题与解决
  9. 基于hanlp的es分词插件
  10. 有关java5以后的线程