基于netty手写Tomcat( 二 )

3.基于netty手写Tomcat

  1. 修改ParentRequest
public class ParentRequest {private ChannelHandlerContext ctx;private HttpRequest req;public ParentRequest(ChannelHandlerContext ctx, HttpRequest req) {this.ctx = ctx;this.req = req;}public String getUrl() {return req.uri();}public String getMethod() {return req.method().name();}public Map<String, List<String>> getParameters() {QueryStringDecoder decoder = new QueryStringDecoder(req.uri());return decoder.parameters();}public String getParameter(String name) {Map<String, List<String>> params = getParameters();List<String> param = params.get(name);if (null == param) {return null;} else {return param.get(0);}}}123456789101112131415161718192021222324252627282930313233
  1. 修改ParentResponse
public class ParentResponse {//SocketChannel的封装private ChannelHandlerContext ctx;private HttpRequest req;public ParentResponse(ChannelHandlerContext ctx, HttpRequest req) {this.ctx = ctx;this.req = req;}public void write(String out) throws Exception {try {if (out == null || out.length() == 0) {return;}// 设置 http协议及请求头信息FullHttpResponse response = new DefaultFullHttpResponse(// 设置http版本为1.1HttpVersion.HTTP_1_1,// 设置响应状态码HttpResponseStatus.OK,// 将输出值写出 编码为UTF-8Unpooled.wrappedBuffer(out.getBytes("UTF-8")));response.headers().set("Content-Type", "text/html;");ctx.write(response);} finally {ctx.flush();ctx.close();}}}12345678910111213141516171819202122232425262728293031323334
  1. 修改TomcatStart
public class TomcatStart {private int port = 8080;private Map<String, ParentServlet> servletMapping = new HashMap<String, ParentServlet>();private Properties webProperties = new Properties();private void init() {try {String WEB_INF = this.getClass().getResource("/").getPath();FileInputStream fis = new FileInputStream(WEB_INF + "web.properties");webProperties.load(fis);for (Object k : webProperties.keySet()) {String key = k.toString();if (key.endsWith(".url")) {String servletName = key.replaceAll("\.url$", "");String url = webProperties.getProperty(key);String className = webProperties.getProperty(servletName + ".className");//单实例多线程ParentServlet obj = (ParentServlet) Class.forName(className).newInstance();servletMapping.put(url, obj);}}} catch (Exception e) {e.printStackTrace();}}public void start() {//1.加载配置类 , 初始化servletMappinginit();// NettyNIO Reactor模型 Boss Worker//Boss 线程EventLoopGroup bossGroup = new NioEventLoopGroup();//Work线程EventLoopGroup workGroup = new NioEventLoopGroup();ServerBootstrap server = null;try {//创建对象server = new ServerBootstrap();//配置参数//链式编程server.group(bossGroup, workGroup)//主线程处理类 , .channel(NIOServerSocketChannel.class)//子线程处理类.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel client) throws Exception {//无锁化串行编程//netty对http的封装 对顺序有要求//httpResponseEncoder 编码器client.pipeline().addLast(new HttpResponseEncoder());//httprequestDecoder 解码器client.pipeline().addLast(new HttpRequestDecoder());//业务处理器client.pipeline().addLast(new TomcatHandler());}})//主线程 线程最大数量128.option(ChannelOption.SO_BACKLOG, 128)//子线程配置 保存长连接.childOption(ChannelOption.SO_KEEPALIVE, true);ChannelFuture f = server.bind(port).sync();System.out.println("Tomcat 已启动 , 监听端口是:" + this.port);f.channel().closeFuture().sync();} catch (Exception e) {e.printStackTrace();} finally {bossGroup.shutdownGracefully();workGroup.shutdownGracefully();}}public class TomcatHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof HttpRequest) {System.out.println("hello request");HttpRequest req = (HttpRequest) msg;ParentRequest request = new ParentRequest(ctx, req);ParentResponse response = new ParentResponse(ctx, req);String url = request.getUrl();if (servletMapping.containsKey(url)) {//7.调用实例化对象的service方法servletMapping.get(url).service(request, response);} else {response.write("404 - Not Found");}}}}public static void main(String[] args) {//启动new TomcatStart().start();}}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697984.访问http://localhost:8080/first
基于netty手写Tomcat

文章插图




推荐阅读