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

使用Netty实现的一个简单HTTP服务器的更多相关文章

  1. 用nodejs搭建一个简单的服务器

    使用nodejs搭建一个简单的服务器 nodejs优点:性能高(读写文件) 数据操作能力强 官网:www.nodejs.org 验证是否安装成功:cmd命令行中输入node -v 如果显示版本号表示安 ...

  2. 初学Node(六)搭建一个简单的服务器

    搭建一个简单的服务器 通过下面的代码可以搭建一个简单的服务器: var http = require("http"); http.createServer(function(req ...

  3. 轻松创建nodejs服务器(1):一个简单nodejs服务器例子

    这篇文章主要介绍了一个简单nodejs服务器例子,本文实现了一个简单的hello world例子,并展示如何运行这个服务器,需要的朋友可以参考下   我们先来实现一个简单的例子,hello world ...

  4. Node学习(二) --使用http和fs模块实现一个简单的服务器

    1.创建一个www目录,存储静态文件1.html.1.jpg. * html文件内容如下: 12345678910111213 <html lang="en">< ...

  5. Express 的基本使用(创建一个简单的服务器)

    Express 的基本使用(创建一个简单的服务器) const express = require('express') // 创建服务器应用程序 // 相当于 http.creatServer co ...

  6. Netty练手项目-简单Http服务器

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

  7. 理解与模拟一个简单web服务器

    先简单说下几个概念,根据自己的理解,不正确请见谅. web服务器 首先要知道什么是web服务器,简单说web服务器就是可以使用HTTP传输协议与客户端进行通信的服务器.最初的web服务器只能用来处理静 ...

  8. Linux:写一个简单的服务器

    开始了新篇章:Linux网络编程. 基础知识: 套接字概念 Socket本身有"插座"的意思,在Linux环境下,用于表示进程间网络通信的特殊文件类型.本质为内核借助缓冲区形成的伪 ...

  9. Windows 上静态编译 Libevent 2.0.10 并实现一个简单 HTTP 服务器(无数截图)

    [文章作者:张宴 本文版本:v1.0 最后修改:2011.03.30 转载请注明原文链接:http://blog.s135.com/libevent_windows/] 本文介绍了如何在 Window ...

随机推荐

  1. ServletContext读取配置文件

    package servlet; import java.io.FileInputStream;import java.io.IOException;import java.io.InputStrea ...

  2. HTML5开发移动web应用——SAP UI5篇(8)

    本次对之前学习的SAP UI5框架知识进行简单小结.以及重点部分知识的梳理. 1.在UI5使用过程中,命名空间的概念非常重要. 2.一般的sap组件引用格式例如以下: sap.ui.define([ ...

  3. 讲真,你是因为什么才买华为P20系列手机!

    华为P20系列手机上市两个半月发货600万台!600万台?!看到这个亮瞎我钛合金狗眼的数据,且容我掰着手指脚趾算一下,算了,还是容我毫不夸张的感叹一句吧:华为做手机不用桨,不需风,全靠“浪”……. 两 ...

  4. jquery单选框radio绑定click事件实现方法

    本文实例讲述了jquery单选框radio绑定click事件实现方法.分享给大家供大家参考. 具体实现方法如下: 复制代码代码如下: <html><head><title ...

  5. 【WPF学习笔记】之如何点登录按钮时判断用户名密码进行登录:动画系列之(二)

    ...... 承接动画系列之(一)的代码: 再添加登录按钮代码进行登录,验证用户名和密码在数据库是否正确. 直接上代码: using System; using System.Collections. ...

  6. React常用方法手记

    1.Reactjs 如何获取子组件的key值?请问antd中table自定义列render方法怎么获取当前第几列? https://segmentfault.com/q/101000000453235 ...

  7. wamp环境配置;转自发瑞的博客(www.cnblogs.com/cyrfr/p/6483529.html)

    php手动搭建环境有好多种组合,版本号不一致,会导致搭建失败. 我搭建的组合是: php5.6+MySQL5.6+Apache2.4的组合. 一.PHP语言包下载 首先从官网上下载php5.6 htt ...

  8. /etc/init.d/iptables stop

    /etc/init.d/iptables stop     systemctl stop firewalld.service   [root@bigdata-server-01 myrestserve ...

  9. Android笔记之ViewModel的使用示例

    依赖 implementation 'android.arch.lifecycle:extensions:1.1.1' implementation 'com.squareup.retrofit2:r ...

  10. Android Development Note-02

    输入框左侧的logo:android:drawableleft   弹出提示: Toast.makeText(this,"提示",Toast.LENGHT_LONG).show() ...