Netty Http服务器
是基于 netty 的 nio 简易 http 服务器
代码展示
public class HttpServer {
Map<String, String> lastData = new HashMap<String, String>() {{
put(".ico", "image/x-icon");
put(".js", "text/javascript; charset=utf-8");
put(".css", "text/css; charset=utf-8");
put(".html", "text/html; charset=utf-8");
put(".png", "image/png");
put(".gif", "image/gif");
}};
{
init();
}
public void init() {
// 创建 group
NioEventLoopGroup boosGroup = new NioEventLoopGroup();
NioEventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(boosGroup, workGroup)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline()
.addLast("Mine", new HttpServerCodec()) // 编码处理器
.addLast("MineHandler", new SimpleChannelInboundHandler<HttpObject>() {
// Http 响应处理器
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject) throws Exception {
if (httpObject instanceof HttpRequest) {
HttpRequest request = ((HttpRequest) httpObject);
String baseUtl = "C:\\Users\\Administrator\\Desktop\\Company\\server";
String uri = request.uri();
// 对于默认的路径跳转做配置
if (uri.equals("/")) uri = "/index.html";
File file = new File(baseUtl + uri);
// 访问指定文件的资源
if (file.exists()) {
if (file.isDirectory()) {
sendMsg(channelHandlerContext, "文件数据拒绝访问");
return;
}
Lock lock = new ReentrantLock();
try (FileInputStream stream = new FileInputStream(file)) {
lock.lock();
if (file.length() > Integer.MAX_VALUE)
sendMsg(channelHandlerContext, "数据量太大");
byte[] b = new byte[(int) file.length()];
String type = uri.substring(uri.lastIndexOf("."));
while (true) {
int read = stream.read(b);
if (read == -1) break;
sendMsg(channelHandlerContext, b, type);
}
} catch (Exception e) {
System.err.println("发生未知异常 => " + e.getMessage());
} finally {
lock.unlock();
}
} else {
System.err.println(uri + " => 数据不存在");
sendMsg(channelHandlerContext, "数据不存在");
}
}
}
});
}
});
ChannelFuture future = serverBootstrap.bind(80).sync();
System.out.println("服务器初始化成功");
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
boosGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
/**
* 返回客户端 404 消息 (也可以配置文件资源)
*
* @param channelHandlerContext 上下文
* @param msg 消息 {@link ByteBuf}
*/
private void sendMsg(ChannelHandlerContext channelHandlerContext, String msg) {
ByteBuf buffer = Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8);
FullHttpResponse response = new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND, buffer
);
response.headers().set(HttpHeaderNames.CONTENT_TYPE, getContentType(null));
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, buffer.readableBytes());
channelHandlerContext.writeAndFlush(response);
}
/**
* 发送消息给服务端
*
* @param channelHandlerContext 上下文
* @param msg 消息 {@link ByteBuf}
* @param type 处理的文件类型
*/
private void sendMsg(ChannelHandlerContext channelHandlerContext, byte[] msg, String type) {
ByteBuf buffer = Unpooled.copiedBuffer(msg);
FullHttpResponse response = new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buffer
);
response.headers().set(HttpHeaderNames.CONTENT_TYPE, getContentType(type));
response.headers().set(HttpHeaderNames.ACCEPT_RANGES, "bytes");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, buffer.readableBytes());
channelHandlerContext.writeAndFlush(response);
}
/**
* 获取文件处理的对应的类型
*
* @param last 后缀
*/
private String getContentType(String last) {
String result = lastData.get(last);
return ObjectUtils.isEmpty(result) ? "text/plain;charset=utf-8" : result;
}
public static void main(String[] args) {
new HttpServer();
}
}
**备注:**就可以通过http://127.0.0.1
访问了