使用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

使用Netty实现的一个简单HTTP服务器的更多相关文章
- 用nodejs搭建一个简单的服务器
使用nodejs搭建一个简单的服务器 nodejs优点:性能高(读写文件) 数据操作能力强 官网:www.nodejs.org 验证是否安装成功:cmd命令行中输入node -v 如果显示版本号表示安 ...
- 初学Node(六)搭建一个简单的服务器
搭建一个简单的服务器 通过下面的代码可以搭建一个简单的服务器: var http = require("http"); http.createServer(function(req ...
- 轻松创建nodejs服务器(1):一个简单nodejs服务器例子
这篇文章主要介绍了一个简单nodejs服务器例子,本文实现了一个简单的hello world例子,并展示如何运行这个服务器,需要的朋友可以参考下 我们先来实现一个简单的例子,hello world ...
- Node学习(二) --使用http和fs模块实现一个简单的服务器
1.创建一个www目录,存储静态文件1.html.1.jpg. * html文件内容如下: 12345678910111213 <html lang="en">< ...
- Express 的基本使用(创建一个简单的服务器)
Express 的基本使用(创建一个简单的服务器) const express = require('express') // 创建服务器应用程序 // 相当于 http.creatServer co ...
- Netty练手项目-简单Http服务器
简单的设计思路就是,启动一个可以截断并处理Http请求的服务器代码.使用netty提供的boss线程与worker线程的模型,并使用netty的http解码器.自行编写了http url处理的部分.在 ...
- 理解与模拟一个简单web服务器
先简单说下几个概念,根据自己的理解,不正确请见谅. web服务器 首先要知道什么是web服务器,简单说web服务器就是可以使用HTTP传输协议与客户端进行通信的服务器.最初的web服务器只能用来处理静 ...
- Linux:写一个简单的服务器
开始了新篇章:Linux网络编程. 基础知识: 套接字概念 Socket本身有"插座"的意思,在Linux环境下,用于表示进程间网络通信的特殊文件类型.本质为内核借助缓冲区形成的伪 ...
- Windows 上静态编译 Libevent 2.0.10 并实现一个简单 HTTP 服务器(无数截图)
[文章作者:张宴 本文版本:v1.0 最后修改:2011.03.30 转载请注明原文链接:http://blog.s135.com/libevent_windows/] 本文介绍了如何在 Window ...
随机推荐
- iOS 10 的杂碎资料
兼容iOS 10 资料整理笔记 1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大 ...
- [转] 盘点8种CSS实现垂直居中水平居中的绝对定位居中技术
转自:http://blog.csdn.net/freshlover/article/details/11579669 Ⅰ.绝对定位居中(Absolute Centering)技术 我们经常用marg ...
- 操作符表示指针指向的底层值 切片 nill 清空 按值引用赋值 获取地址赋值
package main import "fmt" var thisVisitedUrls [] string func tf() { p := &thisVisitedU ...
- Android笔记之引用aar
把要引用的aar文件复制到目录app\libs中(我要引用的aar名为xybigdatasdk-release-out2.2.6.aar) 在build.gradle (Module: app)中添加 ...
- Golang JSON操作汇总
直接把结构体编码成json数据 package main import ( "encoding/json" "fmt" _ "os" ) t ...
- Java中的迭代迭代器Iterator与枚举器Enumeration
Iterator 和 Enumeration区别 Iterator 和 Eumberation都是Collection集合的遍历接口,我们先看下他们的源码接口 package java.util; p ...
- Oracle伪列rownum
Oracle基础知识:伪列rownum,伪列就像表中的列一样,但是在表中并不存储.伪列只能查询,不能进行增删改操作. 在查询的结果集中,ROWNUM为结果集中每一行标识一个行号,第一行返回1,第二行返 ...
- LeetCode:删除链表中的节点【203】
LeetCode:删除链表中的节点[203] 题目描述 删除链表中等于给定值 val 的所有节点. 示例: 输入: 1->2->6->3->4->5->6, val ...
- POJ - 3278 Catch That Cow 【BFS】
题目链接 http://poj.org/problem?id=3278 题意 给出两个数字 N K 每次 都可以用三个操作 + 1 - 1 * 2 求 最少的操作次数 使得 N 变成 K 思路 BFS ...
- Algorithm: dynamic programming
1. Longest Increasing Subsequence (LIS) problem unsorted array, calculate out the maximum length of ...