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 比 Apache 更牛逼
Mar 31 Servers
Nginx+Tomcat实现负载均衡、动静分离的原理解析
Mar 31 Servers
Nginx+SpringBoot实现负载均衡的示例
Mar 31 Servers
学习nginx基础知识
Sep 04 Servers
nginx负载功能+nfs服务器功能解析
Feb 28 Servers
Apache Hudi数据布局黑科技降低一半查询时间
Mar 31 Servers
Windows Server 2019 配置远程控制以及管理方法
Apr 28 Servers
Windows Server 2012 R2 磁盘分区教程
Apr 29 Servers
windows server 2012安装FTP并配置被动模式指定开放端口
Jun 10 Servers
Linux中各个目录的作用与内容
Jun 28 Servers
GPU服务器的多用户配置方法
Jul 07 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
一个ORACLE分页程序,挺实用的.
2006/10/09 PHP
CodeIgniter框架提示Disallowed Key Characters的解决办法
2014/04/21 PHP
PHP获取指定时间段之间的 年,月,天,时,分,秒
2016/06/05 PHP
php指定长度分割字符串str_split函数用法示例
2017/01/30 PHP
php中html_entity_decode实现HTML实体转义
2018/06/13 PHP
js对列表中第一个值处理与jsp页面对列表中第一个值处理的区别详解
2013/11/05 Javascript
自己用jQuery写了一个图片的马赛克消失效果
2014/05/04 Javascript
node.js require() 源码解读
2015/12/13 Javascript
全面介绍javascript实用技巧及单竖杠
2016/07/18 Javascript
原生态js,鼠标按下后,经过了那些单元格的简单实例
2016/08/11 Javascript
JavaScript 随机验证码的生成实例代码
2016/09/22 Javascript
js判断出两个字符串最大子串的函数实现方法
2016/11/01 Javascript
JS中精巧的自动柯里化实现方法
2017/12/12 Javascript
JavaScript实现连连看连线算法
2019/01/05 Javascript
ES6 Proxy实现Vue的变化检测问题
2019/06/11 Javascript
Angular8 Http拦截器简单使用教程
2019/08/20 Javascript
vue中提示$index is not defined错误的解决方式
2020/09/02 Javascript
[03:34]2014DOTA2西雅图国际邀请赛 淘汰赛7月15日TOPPLAY
2014/07/15 DOTA
[00:34]TI7不朽珍藏III——地穴编织者不朽展示
2017/07/15 DOTA
python去掉字符串中重复字符的方法
2014/02/27 Python
Python实现扫描指定目录下的子目录及文件的方法
2014/07/16 Python
在Django的视图中使用数据库查询的方法
2015/07/16 Python
python爬虫爬取淘宝商品信息(selenum+phontomjs)
2018/02/24 Python
Python+OpenCV图片局部区域像素值处理详解
2019/01/23 Python
PyQt5 加载图片和文本文件的实例
2019/06/14 Python
python threading和multiprocessing模块基本用法实例分析
2019/07/25 Python
python读取指定字节长度的文本方法
2019/08/27 Python
python实现滑雪者小游戏
2020/02/22 Python
关于win10在tensorflow的安装及在pycharm中运行步骤详解
2020/03/16 Python
使用Django实现把两个模型类的数据聚合在一起
2020/03/28 Python
python ETL工具 pyetl
2020/06/07 Python
python os.rename实例用法详解
2020/12/06 Python
浅析Python打包时包含静态文件处理方法
2021/01/15 Python
国际贸易专业求职信
2014/06/04 职场文书
医院义诊活动总结
2014/07/04 职场文书
名人演讲稿范文
2014/09/16 职场文书