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 相关文章推荐
Windows下使用Nginx+Tomcat做负载均衡的完整步骤
Mar 31 Servers
Nginx解决403 forbidden的完整步骤
Apr 01 Servers
nginx结合openssl实现https的方法
Jul 25 Servers
Apache POI的基本使用详解
Nov 07 Servers
微信告警的zabbix监控系统 监控整个NGINX集群
Apr 18 Servers
安装harbor作为docker镜像仓库的问题
Jun 14 Servers
Windows Server 修改远程桌面端口的实现
Jun 25 Servers
win sever 2022如何占用操作主机角色
Jun 25 Servers
Win2008系统搭建DHCP服务器
Jun 25 Servers
Windows Server 2008配置防火墙策略详解
Jun 28 Servers
apache虚拟主机配置的三种方式(小结)
Jul 23 Servers
ubuntu开机后ROS程序自启动问题
Dec 24 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
网页游戏开发入门教程三(简单程序应用)
2009/11/02 PHP
php zip文件解压类代码
2009/12/02 PHP
PHP用GD库生成高质量的缩略图片
2011/03/09 PHP
PHP中通过语义URL防止网站被攻击的方法分享
2011/09/08 PHP
PHP实现的支付宝支付功能示例
2019/03/26 PHP
菜单效果
2006/10/14 Javascript
拖动一个HTML元素
2006/12/22 Javascript
Windows Live的@live.com域名注册漏洞 利用代码
2006/12/27 Javascript
JavaScript的Cookies
2008/01/16 Javascript
jquery左右滚动焦点图banner图片鼠标经过显示上下页按钮
2013/10/11 Javascript
jquery选择器之层级过滤选择器详解
2014/01/27 Javascript
原生js实现fadein 和 fadeout淡入淡出效果
2014/06/05 Javascript
JavaScript实现网页截图功能
2014/10/16 Javascript
Javascript 5种方法实现过滤删除前后所有空格
2016/06/22 Javascript
vue实现ToDoList简单实例
2017/02/07 Javascript
Vue.js 2.0 移动端拍照压缩图片预览及上传实例
2017/04/27 Javascript
JS+WCF实现进度条实时监测数据加载量的方法详解
2017/12/19 Javascript
nginx+vue.js实现前后端分离的示例代码
2018/02/12 Javascript
浅谈React的最大亮点之虚拟DOM
2018/05/29 Javascript
vue拖拽排序插件vuedraggable使用方法详解
2020/08/21 Javascript
nodejs微信开发之自动回复的实现
2019/03/17 NodeJs
浅谈express.js框架中间件(middleware)
2019/04/07 Javascript
在vue项目中引用Antv G2,以饼图为例讲解
2020/10/28 Javascript
Django中使用locals()函数的技巧
2015/07/16 Python
Python实现的直接插入排序算法示例
2018/04/29 Python
在Python 中同一个类两个函数间变量的调用方法
2019/01/31 Python
python爬虫学习笔记之pyquery模块基本用法详解
2020/04/09 Python
Python JSON常用编解码方法代码实例
2020/09/05 Python
10个最常见的HTML5面试题 附答案
2016/06/06 HTML / CSS
Sarenza德国:法国最大的时尚鞋和包包网上商店
2019/06/08 全球购物
耐克波兰官方网站:Nike波兰
2019/09/03 全球购物
法学毕业生自荐信
2013/11/13 职场文书
幼儿教师师德培训心得体会
2016/01/09 职场文书
python第三方网页解析器 lxml 扩展库与 xpath 的使用方法
2021/04/06 Python
介绍一下28个JS常用数组方法
2022/05/06 Javascript