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开启Brotli压缩算法实现过程详解
Mar 31 Servers
Nginx location 和 proxy_pass路径配置问题小结
Sep 04 Servers
使用 Apache Dubbo 实现远程通信(微服务架构)
Feb 12 Servers
Apache Linkis 中间件架构及快速安装步骤
Mar 16 Servers
nginx rewrite功能使用场景分析
May 30 Servers
V Rising 服务器搭建图文教程
Jun 16 Servers
教你nginx跳转配置的四种方式
Jul 07 Servers
Nginx代理Redis哨兵主从配置的实现
Jul 15 Servers
zabbix 代理服务器的部署与 zabbix-snmp 监控问题
Jul 15 Servers
Windows Server 2016服务器用户管理及远程授权图文教程
Aug 14 Servers
zabbix如何添加监控主机和自定义监控项
Aug 14 Servers
Fluentd搭建日志收集服务
Sep 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
全国FM电台频率大全 - 7 吉林省
2020/03/11 无线电
php+ajax实现无刷新分页的方法
2014/11/04 PHP
ubuntu下配置nginx+php+mysql详解
2015/09/10 PHP
php+ajax实现带进度条的上传图片功能【附demo源码下载】
2016/09/14 PHP
Yii2框架中一些折磨人的坑
2019/12/15 PHP
php使用fputcsv实现大数据的导出操作详解
2020/02/27 PHP
基于jquery的用鼠标画出可移动的div
2012/09/06 Javascript
IE6-8中Date不支持toISOString的修复方法
2014/05/04 Javascript
js控制文本框只输入数字和小数点的方法
2015/03/10 Javascript
jQuery时间戳和日期相互转换操作示例
2018/12/07 jQuery
微信小程序开发之左右分栏效果的实例代码
2019/05/20 Javascript
解决Vue.js应用回退或刷新界面时提示用户保存修改问题
2019/11/24 Javascript
用Python脚本生成Android SALT扰码的方法
2013/09/18 Python
Python中为feedparser设置超时时间避免堵塞
2014/09/28 Python
利用python实现xml与数据库读取转换的方法
2017/06/17 Python
python爬虫框架scrapy实现模拟登录操作示例
2018/08/02 Python
python实现字符串中字符分类及个数统计
2018/09/28 Python
Python3爬虫全国地址信息
2019/01/05 Python
Python中使用__new__实现单例模式并解析
2019/06/25 Python
pybind11在Windows下的使用教程
2019/07/04 Python
linux下python中文乱码解决方案详解
2019/08/28 Python
基于python判断目录或者文件代码实例
2019/11/29 Python
Python的对象传递与Copy函数使用详解
2019/12/26 Python
Python如何根据时间序列数据作图
2020/05/12 Python
opencv+pyQt5实现图片阈值编辑器/寻色块阈值利器
2020/11/13 Python
CSS3 简单又实用的5个属性
2010/03/04 HTML / CSS
浅谈CSS3动画的回调处理
2016/07/21 HTML / CSS
HTML5 canvas 基本语法
2009/08/26 HTML / CSS
canvas简易绘图的实现(海绵宝宝篇)
2018/07/04 HTML / CSS
商学院大学生求职的自我评价
2014/03/12 职场文书
村党的群众路线教育实践活动工作总结
2014/10/25 职场文书
自主招生自荐信格式
2015/03/04 职场文书
跟班学习心得体会(共6篇)
2016/01/23 职场文书
新店开业策划方案怎么书写?
2019/07/05 职场文书
Go语言 go程释放操作(退出/销毁)
2021/04/30 Golang
Python  lambda匿名函数和三元运算符
2022/04/19 Python