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的rewrite模块详解
Mar 31 Servers
apache基于端口创建虚拟主机的示例
Apr 24 Servers
Nginx速查手册及常见问题
Apr 07 Servers
Nginx动静分离配置实现与说明
Apr 07 Servers
使用 Docker Compose 构建复杂的多容器App
Apr 30 Servers
centos7安装mysql5.7经验记录
May 02 Servers
nginx实现多geoserver服务的负载均衡
May 15 Servers
项目中Nginx多级代理是如何获取客户端的真实IP地址
May 30 Servers
Nginx开源可视化配置工具NginxConfig使用教程
Jun 21 Servers
Windows Server 修改远程桌面端口的实现
Jun 25 Servers
Fluentd搭建日志收集服务
Sep 23 Servers
Zabbix6通过ODBC方式监控Oracle 19C的详细过程
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
BBS(php &amp; mysql)完整版(六)
2006/10/09 PHP
php date()日期时间函数详解
2010/05/16 PHP
php入门学习知识点二 PHP简单的分页过程与原理
2011/07/14 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(一)
2014/06/23 PHP
phpQuery让php处理html代码像jQuery一样方便
2015/01/06 PHP
javascript中&quot;/&quot;运算符常见错误
2010/10/13 Javascript
基于jQuery实现左右div自适应高度完全相同的代码
2012/08/09 Javascript
javascript获得网页窗口实际大小的示例代码
2013/09/21 Javascript
js判断上传文件的类型和大小示例代码
2013/10/18 Javascript
全面理解面向对象的 JavaScript(来自ibm)
2013/11/10 Javascript
jQuery探测位置的提示弹窗(toolTip box)详细解析
2013/11/14 Javascript
js的回调函数详解
2015/01/05 Javascript
在JavaScript中处理字符串之fontcolor()方法的使用
2015/06/08 Javascript
js带前后翻页的图片切换效果代码分享
2015/09/08 Javascript
JS定义类的六种方式详解
2016/05/12 Javascript
jQuery使用getJSON方法获取json数据完整示例
2016/09/13 Javascript
vue.js 表格分页ajax 异步加载数据
2016/10/18 Javascript
微信 java 实现js-sdk 图片上传下载完整流程
2016/10/21 Javascript
原生Javascript插件开发实践
2017/01/18 Javascript
node.js中实现kindEditor图片上传功能的方法教程
2017/04/26 Javascript
JavaScript检测是否开启了控制台(F12调试工具)
2020/10/02 Javascript
python操作gmail实例
2015/01/14 Python
python 打印对象的所有属性值的方法
2016/09/11 Python
Python实现基于SVM的分类器的方法
2019/07/19 Python
Python使用多进程运行含有任意个参数的函数
2020/05/02 Python
css3 条纹化和透明化表格Firefox下测试成功
2014/04/15 HTML / CSS
美国皮靴公司自1863年:The Frye Company
2016/11/30 全球购物
奢华时尚的独特视角:La Garçonne
2018/06/07 全球购物
早晨薰衣草在线女性精品店:Morning Lavender
2021/01/04 全球购物
对标管理实施方案
2014/03/12 职场文书
《音乐之都维也纳》教学反思
2014/04/16 职场文书
2014年社区矫正工作总结
2014/11/18 职场文书
2014年世界艾滋病日演讲稿
2014/11/28 职场文书
2014工程部年度工作总结
2014/12/17 职场文书
护士医德考评自我评价
2015/03/03 职场文书
西游降魔篇观后感
2015/06/15 职场文书