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

  初始化扫描会指定扫描controller.container下的类,使用了自定义Annotation并且单例的方式加载,未考虑太多细节就为了好玩。

  接下来使用postman尝试调用接口。

  一个简单的netty搭建的web服务就完成了。

package server;

import handler.HttpServerHandler;
import initScan.InitialProcess;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpServerCodec; /**
* Created by MacBook on 2019/7/14.
*/
public class ServerStarter { private EventLoopGroup boss ; private EventLoopGroup worker ; private int port; private static int DEFAULT_PORT = 8080; public ServerStarter(){
boss = new NioEventLoopGroup();
worker = new NioEventLoopGroup();
port = DEFAULT_PORT;
} public ServerStarter(int port){
this();
if(port < 0 || port > 65535){
throw new IllegalArgumentException("port:"+port+" is illegal");
}
this.port = port;
} public void startup() throws InterruptedException{ if(boss.isShutdown() || worker.isShutdown()){
throw new IllegalStateException("server was closed");
} // 初始化容器
InitialProcess initialProcess = new InitialProcess();
initialProcess.init(); ServerBootstrap serverBootstrap = new ServerBootstrap();
System.out.println("=====http server start ");
serverBootstrap.channel(NioServerSocketChannel.class)
.group(boss,worker)
.childOption(ChannelOption.SO_KEEPALIVE,true)
.option(ChannelOption.SO_BACKLOG,1024)
.childHandler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("http-decode",new HttpServerCodec());
socketChannel.pipeline().addLast(new HttpServerHandler());
}
}); ChannelFuture future = serverBootstrap.bind(port).sync(); System.out.println("server port listen:"+port); future.channel().closeFuture().sync(); shutDownGracefully();
} /**
* 关闭管道
*/
public void shutDownGracefully(){
this.boss.shutdownGracefully();
this.worker.shutdownGracefully();
} }

  这是服务器启动的核心代码,首先初始化两个Nio线程组,把它们绑定到ServerBootstrap里,并添加Handler。

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import controller.Properties;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import response.BaseResponse; import java.lang.reflect.Method; /**
* Created by MacBook on 2019/7/14.
*/
public class HttpServerHandler extends ChannelInboundHandlerAdapter{ @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if(msg instanceof HttpRequest){
HttpRequest request = (HttpRequest)msg;
// boolean keepAlive = HttpUtil.isKeepAlive(request); System.out.println("http request method :"+request.method());
System.out.println("http request uri : "+request.uri()); Object controller = Properties.urlController.get(request.uri());
Method m = Properties.urlMethod.get(request.uri());
if(controller == null){
FullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND);
ctx.writeAndFlush(httpResponse).addListener(ChannelFutureListener.CLOSE); }else {
FullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json");
Object result = m.invoke(controller); httpResponse.content().writeBytes(JSON.toJSONString(result,SerializerFeature.WriteMapNullValue).getBytes()); ctx.writeAndFlush(httpResponse).addListener(ChannelFutureListener.CLOSE);
} }
}
}

  这是处理器的代码,在经过第一个Http解码器之后,进来的对象msg已经被转化为HttpRequest了。

Netty练手项目-简单Http服务器的更多相关文章

  1. 微信小程序初体验,入门练手项目--通讯录,后台是阿里云服务器(一)

    内容: 一.前言 二.相关概念 三.开始工作 四.启动项目起来 五.项目结构 六.设计理念 七.路由 八.部署线上后端服务 同步交流学习社区: https://www.mwcxs.top/page/4 ...

  2. web前端学习部落22群分享给需要前端练手项目

    前端学习还是很有趣的,可以较快的上手然后自己开发一些好玩的项目来练手,网上也可以一抓一大把关于前端开发的小项目,可是还是有新手在学习的时候不知道可以做什么,以及怎么做,因此,就整理了一些前端项目教程, ...

  3. Python之路【第二十四篇】:Python学习路径及练手项目合集

      Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...

  4. 推荐:一个适合于Python新手的入门练手项目

    随着人工智能的兴起,国内掀起了一股Python学习热潮,入门级编程语言,大多选择Python,有经验的程序员,也开始学习Python,正所谓是人生苦短,我用Python 有个Python入门练手项目, ...

  5. 80个Python练手项目列表

    80个Python练手项目列表   我若将死,给孩子留遗言,只留一句话:Repetition is the mother of all learning重复是学习之母.他们将来长大,学知识,技巧.爱情 ...

  6. webpack练手项目之easySlide(三):commonChunks(转)

    Hello,大家好. 在之前两篇文章中: webpack练手项目之easySlide(一):初探webpack webpack练手项目之easySlide(二):代码分割 与大家分享了webpack的 ...

  7. webpack练手项目之easySlide(二):代码分割(转)

    在上一篇 webpack练手项目之easySlide(一):初探webpack  中我们一起为大家介绍了webpack的基本用法,使用webpack对前端代码进行模块化打包. 但是乍一看webpack ...

  8. 练手项目:利用pygame库编写射击游戏

    本项目使用pygame模块编写了射击游戏,目的在于训练自己的Python基本功.了解中小型程序框架以及学习代码重构等.游戏具有一定的可玩性,感兴趣的可以试一下. 项目说明:出自<Python编程 ...

  9. 适合Python的5大练手项目, 你练了么?

    在练手项目的选择上,还存在疑问?不知道要从哪种项目先下手? 首先有两点建议: 最好不要写太应用的程序练手,要思考什么更像是知识,老只会写写爬虫是无用的,但是完全不写也不行. 对于练手的程序,要注意简化 ...

随机推荐

  1. linux简单命令10---权限

    1:文件权限设置 数字的用法:chmod 755 文件名 ---------------------------------------------下面是文件权限------------------- ...

  2. delphi stringgrid导出为excel

    procedure TLiYQBYJL.btnBYJLTJDCClick(Sender: TObject); var ExcelApp, workbook, sheet: Variant; col, ...

  3. eclipse中Maven web项目的目录结构浅析

    刚开始接触maven web项目的时候,相信很多人都会被它的目录结构迷惑. 为了避免初学者遇到像我一样的困扰,我就从一个纯初学者的视角,来分析一下这个东西. 1,比如说,我们拿一个常见的目录结构来看, ...

  4. 使用robotframework做接口测试5——一个用例中调多个接口

    凡是涉及一点点有接口关联的,都可能下一个接口需要上一个接口的某个返回值作为入参,最直接的例子,就是登录依赖.用接口做业务性的测试,也绝对离不开接口依赖的,业务都是一系列接口串联的结果,有时候一个接口操 ...

  5. 转:微服务框架之微软Service Fabric

    常见的微服务架构用到的软件&组件: docker(成熟应用) spring boot % spring cloud(技术趋势) Service Fabric(属于后起之秀 背后是微软云的驱动) ...

  6. 2019Java常见面试上

    一.开场白简单的介绍一下自己的工作经历与职责,在校或者工作中主要的工作内容,主要负责的内容:(你的信息一清二白的写在简历上,能答出来的最好写在上面,模棱两可不是很清楚的最好不要写,否则会被问的很尴尬) ...

  7. Sequelize+MySQL存储emoji表情

    一.原因 mysql的utf8编码的一个字符最多3个字节,但是一个emoji表情为4个字节,所以utf8不支持存储emoji表情.但是utf8的超集utf8mb4一个字符最多能有4字节,所以能支持em ...

  8. android简易跑马灯

    重点:焦点的选择(返回true使得焦点不被选择) MarqueeText.java package com.example.demo02; import android.content.Context ...

  9. PTA(Advanced Level)1025.PAT Ranking

    To evaluate the performance of our first year CS majored students, we consider their grades of three ...

  10. 剑指offer7: 斐波那契数列第n项(从0开始,第0项为0)

    1. 题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0).n<=39 2. 思路和方法 斐波那契数列(Fibonacci sequen ...