使用Netty实现的一个简单HTTP服务器

1.HttpServer,Http服务启动类,用于初始化各种线程和通道

public class HttpServer {
    public void bind(int port) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childHandler(new HttpChannelInitService()).option(ChannelOption.SO_BACKLOG, 128) 
                        .childOption(ChannelOption.SO_KEEPALIVE, true);


            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
    
     public static void main(String[] args) throws Exception {
            int port = 8080;
            if (args != null && args.length > 0) {
                try {
                    port = Integer.valueOf(args[0]);
                } catch (NumberFormatException e) {

                }
            }
            new HttpServer().bind(port);
        }
}

 

2.HttpChannelInitService,通道初始化类

public class HttpChannelInitService extends  ChannelInitializer<SocketChannel>{
    @Override
    protected void initChannel(SocketChannel sc)
            throws Exception {
        sc.pipeline().addLast(new HttpResponseEncoder());
        
        sc.pipeline().addLast(new HttpRequestDecoder());

        sc.pipeline().addLast(new HttpChannelHandler());
    }
    
}

 

3.HttpChannelHandler,处理请求的HTTP信息

public class HttpChannelHandler extends ChannelInboundHandlerAdapter {
        
     private HttpRequest request = null;
     private FullHttpResponse response = null;

     @Override
     public void channelRead(ChannelHandlerContext ctx, Object msg)
                throws Exception {
         if (msg instanceof HttpRequest) {
                request = (HttpRequest) msg;
                String uri = request.getUri();
                String res = "";
                try {
                    res = ReadUtils.readFile(uri.substring(1));
                    response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK, Unpooled.wrappedBuffer(res.getBytes("UTF-8")));
                    setJsessionId(isHasJsessionId());
                    setHeaders(response);
                } catch (Exception e) {//处理出错,返回错误信息
                    res = "<html><body>Server Error</body></html>";
                    response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK, Unpooled.wrappedBuffer(res.getBytes("UTF-8")));
                    setHeaders(response);
                    
                }
                if(response!=null)
                    ctx.write(response);
            }
            if (msg instanceof HttpContent) {
                HttpContent content = (HttpContent) msg;
                ByteBuf buf = content.content();
                System.out.println(buf.toString(CharsetUtil.UTF_8));
                buf.release();
            }
        }
     /**
     * 设置HTTP返回头信息
     */
    private void setHeaders(FullHttpResponse response) {
        response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/html");
        response.headers().set(HttpHeaders.Names.CONTENT_LANGUAGE, response.content().readableBytes());
        if (HttpHeaders.isKeepAlive(request)) {
            response.headers().set(HttpHeaders.Names.CONNECTION, Values.KEEP_ALIVE);
        }
    }
    /**
     * 设置JSESSIONID
     */
    private void setJsessionId(boolean isHasJsessionId) {
        if(!isHasJsessionId){
            CookieEncoder encoder = new CookieEncoder(true);
            encoder.addCookie(HttpSession.SESSIONID, HttpSessionManager.getSessionId());
            String encodedCookie = encoder.encode(); 
            response.headers().set(HttpHeaders.Names.SET_COOKIE, encodedCookie); 
        }
    }

    /**
     * 从cookie中获取JSESSIONID信息
     * 判断服务器是否有客户端的JSESSIONID
     * @author yangsong
     * @date 2015年3月26日 下午2:08:07
     */
    private boolean isHasJsessionId() {
        try {
            String cookieStr = request.headers().get("Cookie");
            Set<Cookie> cookies = CookieDecoder.decode(cookieStr);
            Iterator<Cookie> it = cookies.iterator();
            
            while(it.hasNext()){
                Cookie cookie = it.next();
                if(cookie.getName().equals(HttpSession.SESSIONID)){
                    if(HttpSessionManager.isHasJsessionId(cookie.getValue())){
                        return true;
                    }
                    System.out.println("JSESSIONID:"+cookie.getValue());
                        
                }
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return false;
    }
     
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            System.out.println("server channelReadComplete..");
            ctx.flush();//刷新后才将数据发出到SocketChannel
        }
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
                throws Exception {
            System.out.println("server exceptionCaught..");
            ctx.close();
        }
}

 

5.HttpSessionManager,Session管理类

/**
 * HttpSession管理器
 */
public class HttpSessionManager {

    private static final HashMap<String,HttpSession> sessionMap = new HashMap<String, HttpSession>();
    
    /**
     * 创建一个session并返回sessionId
     */
    public  static String getSessionId(){
        synchronized (sessionMap) {
            HttpSession httpSession = new HttpSession();
            sessionMap.put(httpSession.getSessionID(), httpSession);
            return httpSession.getSessionID();
        }
    }
    /**
     * 判断服务器是否包含该客户端的session信息
     */
    public static boolean isHasJsessionId(String sessiondId){
        synchronized (sessionMap) {
            return sessionMap.containsKey(sessiondId);
        }
    }
    
}

6.页面信息与cookie

技术分享

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。