netty 实现tomcat的示例代码


Posted in Servers onJune 05, 2022

netty 实现tomcat

自定义基础类

TomcatServlet

public abstract class TomcatServlet {
 
    public void service(ServletRequest request, ServletResponse response){
        if ("GET".equalsIgnoreCase(request.getMethod())){
            doGet(request, response);
        }else if ("POST".equalsIgnoreCase(request.getMethod())){
            doPost(request, response);
        }else {
            doResponse(response, "暂不支持其它请求方法");
        }
    }
 
    public abstract void doGet(ServletRequest request, ServletResponse response);
    public abstract void doPost(ServletRequest request, ServletResponse response);
 
    public void doResponse(ServletResponse response, String message){
        response.write(message);
    }
}

ServletRequest

@Data
public class ServletRequest {
 
    private ChannelHandlerContext context;
    private HttpRequest httpRequest;
 
    public ServletRequest(){
 
    }
 
    public ServletRequest(ChannelHandlerContext context, HttpRequest httpRequest){
        this.context = context;
        this.httpRequest = httpRequest;
    }
 
    public String getMethod(){
        return httpRequest.method().name();
    }
 
    public HttpHeaders getHeaders(){
        return httpRequest.headers();
    }
 
    public Map<String, List<String>> getParameters(){
        QueryStringDecoder decoder = new QueryStringDecoder(httpRequest.uri());
        return decoder.parameters();
    }
 
    public Map<String,String> getPostFormParameters(){
        Map<String,String> params = new HashMap<>();
 
        HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(httpRequest);
        decoder.getBodyHttpDatas().forEach(item -> {
            if (item.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute){
                Attribute attribute = (Attribute) item;
 
                try {
                    String key = attribute.getName();
                    String value = attribute.getValue();
 
                    params.put(key, value);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
 
        return params;
    }
 
    public Map<String, Object> getPostBody(){
        ByteBuf content = ((FullHttpRequest)httpRequest).content();
        byte[] bytes = new byte[content.readableBytes()];
        content.readBytes(bytes);
 
        return JSON.parseObject(new String(bytes)).getInnerMap();
    }
}

ServletResponse

@Data
public class ServletResponse {
 
    private ChannelHandlerContext context;
    private HttpRequest httpRequest;
 
    public ServletResponse(){
 
    }
 
    public ServletResponse(ChannelHandlerContext context, HttpRequest httpRequest){
        this.context = context;
        this.httpRequest = httpRequest;
    }
 
    public void write(String message){
        FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        response.headers().set("Content-Type","application/json;charset=utf-8");
        response.content().writeCharSequence(message, StandardCharsets.UTF_8);
 
        context.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
}

CustomServlet

ublic class CustomServlet extends TomcatServlet{
 
    @Override
    public void doGet(ServletRequest request, ServletResponse response) {
        System.out.println("处理GET请求");
        System.out.println("请求参数为:");
        request.getParameters().forEach((key,value) -> System.out.println(key + " ==> "+value));
 
        doResponse(response, "GET success");
    }
 
    @Override
    public void doPost(ServletRequest request, ServletResponse response) {
        if (request.getHeaders().get("Content-Type").contains("x-www-form-urlencoded")){
            System.out.println("处理POST Form请求");
            System.out.println("请求参数为:");
            request.getPostFormParameters().forEach((key,value) -> System.out.println(key + " ==> " + value));
 
            doResponse(response, "POST Form success");
        }else if (request.getHeaders().get("Content-Type").contains("application/json")){
            System.out.println("处理POST json请求");
            System.out.println("请求参数为:");
            request.getPostBody().forEach((key,value) -> System.out.println(key + " ==> " + value));
 
            doResponse(response, "POST json success");
        }else {
            doResponse(response, "error:暂不支持其它post请求方式");
        }
    }
}

ServletMapping:url与对应的TomcatServlet映射

public class ServletMapping {
 
    private static final Map<String,TomcatServlet> urlServletMapping = new HashMap<>();
 
    public static Map<String, TomcatServlet> getUrlServletMapping(){
        return urlServletMapping;
    }
}

web.properties:使用properties存储url与对应的TomcatServet

servlet.url=/hello
servlet.className=com.example.demo.tomcat.servlet.CustomServlet

netty 服务端

CustomServerHandler

public class CustomServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
 
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest request) throws Exception {
        String uri = request.uri();
        String path = uri;
        if (uri.contains("?")){
            path = uri.substring(0,uri.indexOf("?"));
        }
 
        if (ServletMapping.getUrlServletMapping().containsKey(path)){
            ServletRequest servletRequest = new ServletRequest(channelHandlerContext, request);
            ServletResponse servletResponse = new ServletResponse(channelHandlerContext, request);
 
            ServletMapping.getUrlServletMapping().get(path).service(servletRequest, servletResponse);
        }else {
            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
            response.content().writeCharSequence("404 NOT FOUND:"+path+"不存在", StandardCharsets.UTF_8);
 
            channelHandlerContext.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
        }
    }
}

NettyServer

public class NettyServer {
 
    private static final Properties webProperties = new Properties();
 
    public static void init(){
        try {
            InputStream inputStream = new FileInputStream("./web.properties");
            webProperties.load(inputStream);
 
            for (Object item : webProperties.keySet()){
                String key = (String)item;
                if (key.endsWith(".url")){
                    String servletKey = key.replaceAll("\\.url","\\.className");
                    String servletName = webProperties.getProperty(servletKey);
 
                    TomcatServlet servlet = (TomcatServlet) Class.forName(servletName).newInstance();
                    ServletMapping.getUrlServletMapping().put(webProperties.getProperty(key),servlet);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
 
    public static void startServer(int port){
        init();
 
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
 
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
 
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline channelPipeline = socketChannel.pipeline();
                            channelPipeline.addLast(new HttpRequestDecoder());
                            channelPipeline.addLast(new HttpResponseEncoder());
                            channelPipeline.addLast(new HttpObjectAggregator(65535));
                            channelPipeline.addLast(new CustomServerHandler());
                        }
                    });
 
            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
            channelFuture.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
 
    public static void main(String[] args) {
        startServer(8000);
    }
}

使用测试

get请求:localhost:8000/hello?name=瓜田李下&age=20

netty 实现tomcat的示例代码

处理GET请求
请求参数为:
name ==> [瓜田李下]
age ==> [20]

get请求:localhost:8000/hello2?name=瓜田李下&age=20

netty 实现tomcat的示例代码

/hello2路径没有对应的TomcatServlet处理

Post form请求:x-www-form-urlencoded

netty 实现tomcat的示例代码

处理POST Form请求
请求参数为:
name ==> 瓜田李下
age ==> 20

Post json请求

netty 实现tomcat的示例代码

处理POST json请求
请求参数为:
name ==> 瓜田李下
age ==> 20

Post form-data请求

netty 实现tomcat的示例代码

目前只支持x-www-form-urlencoded、post json请求,不支持其它请求方式

Put:localhost:8000/hello?name=瓜田李下&age=20

netty 实现tomcat的示例代码

目前只支持GET、POST请求方法,不支持其它方法

到此这篇关于netty 实现tomcat的文章就介绍到这了,更多相关netty 实现tomcat内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!


Tags in this post...

Servers 相关文章推荐
nginx前后端同域名配置的方法实现
Mar 31 Servers
Nginx搭建rtmp直播服务器实现代码
Mar 31 Servers
zabbix自定义监控nginx状态实现过程
Nov 01 Servers
基于Apache Hudi在Google云构建数据湖平台的思路详解
Apr 07 Servers
openstack云计算keystone组件工作介绍
Apr 20 Servers
docker compose 部署 golang 的 Athens 私有代理问题
Apr 28 Servers
Nginx 匹配方式
May 15 Servers
docker 制作mysql镜像并自动安装
May 20 Servers
vscode远程免密登入Linux服务器的配置方法
Jun 28 Servers
TaiShan 200服务器安装Ubuntu 18.04的图文教程
Jun 28 Servers
Linux中一对多配置日志服务器的详细步骤
Jul 23 Servers
基于docker安装zabbix的详细教程
Jun 05 #Servers
linux目录管理方法介绍
Jun 01 #Servers
Linux磁盘管理方法介绍
Jun 01 #Servers
Linux中文件的基本属性介绍
Jun 01 #Servers
解决Vmware虚拟机安装centos8报错“Section %Packages Does Not End With %End. Pane Is Dead”
Jun 01 #Servers
阿里云服务器部署RabbitMQ集群的详细教程
Nginx本地配置SSL访问的实例教程
May 30 #Servers
You might like
php面向对象全攻略 (十六) 对象的串行化
2009/09/30 PHP
一个PHP的ZIP压缩类分享
2014/05/04 PHP
php中strstr、strrchr、substr、stristr四个函数的区别总结
2014/09/22 PHP
php-redis中的sort排序函数总结
2015/07/08 PHP
PHP批量去除BOM头内容信息代码
2016/03/11 PHP
php读取和保存base64编码的图片内容
2017/04/22 PHP
微信第三方登录(原生)demo【必看篇】
2017/05/26 PHP
JavaScript 创建对象和构造类实现代码
2009/07/30 Javascript
js 操作select相关方法函数
2009/12/06 Javascript
jQuery $.each的用法说明
2010/03/22 Javascript
JavaScript 创建运动框架的实现代码
2013/05/08 Javascript
jQuery对JSON数据进行排序输出的方法
2015/06/24 Javascript
详解WordPress开发中get_current_screen()函数的使用
2016/01/11 Javascript
Bootstrap3学习笔记(三)之表格
2016/05/20 Javascript
jQuery post数据至ashx实例详解
2016/11/18 Javascript
jQuery 获取select选中值及清除选中状态
2016/12/13 Javascript
CSS3 动画卡顿性能优化的完美解决方案
2018/09/20 Javascript
微信小程序中为什么使用var that=this
2019/08/27 Javascript
微信小程序wxml列表渲染原理解析
2019/11/27 Javascript
vue 清空input标签 中file的值操作
2020/07/21 Javascript
[20:46]Ti4循环赛第三日VG vs DK
2014/07/12 DOTA
[59:30]VG vs LGD 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.22
2019/09/05 DOTA
Python写的一个简单监控系统
2015/06/19 Python
python编程培训 python培训靠谱吗
2018/01/17 Python
Python装饰器用法示例小结
2018/02/11 Python
Python键盘输入转换为列表的实例
2018/06/23 Python
python format 格式化输出方法
2018/07/16 Python
浅谈python之新式类
2018/08/12 Python
python实现对图片进行旋转,放缩,裁剪的功能
2019/08/07 Python
Pycharm及python安装详细步骤及PyCharm配置整理(推荐)
2020/07/31 Python
python实现将中文日期转换为数字日期
2020/07/14 Python
python 合并多个excel中同名的sheet
2021/01/22 Python
浅谈HTML5 服务器推送事件(Server-sent Events)
2017/08/01 HTML / CSS
2015年禁毒宣传活动总结
2015/03/25 职场文书
雨雪天气温馨提示
2015/07/15 职场文书
纯html+css实现打字效果
2021/08/02 HTML / CSS