Netty(27)Netty的拦截器和过滤器是什么?如何使用它们?

在Netty中,拦截器和过滤器通常指的是在处理网络请求和响应时,插入到ChannelPipeline中的各种处理器(Handler)。这些处理器可以对数据进行拦截、修改、过滤、记录等操作,类似于Servlet中的过滤器或Spring中的拦截器。

1. Netty的拦截器和过滤器概述

  • 拦截器(Interceptor) :通常指的是能够在请求或响应处理的某个阶段进行拦截,并对其进行处理的机制。在Netty中,ChannelHandler可以起到拦截器的作用。
  • 过滤器(Filter) :通常指的是对数据进行过滤、修改等操作的机制。在Netty中,ChannelHandler也可以起到过滤器的作用。

2. 如何使用拦截器和过滤器

在Netty中,拦截器和过滤器的实现主要依赖于ChannelHandler和ChannelPipeline。通过将不同的ChannelHandler添加到ChannelPipeline中,可以实现各种拦截和过滤功能。

3. 代码示例

以下是一个详细的代码示例,展示了如何在Netty中使用拦截器和过滤器。

1. 定义一个简单的服务器

首先,我们定义一个简单的服务器,它将接收客户端的消息并返回响应。

java 复制代码
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class SimpleServer {
    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 protected void initChannel(SocketChannel ch) throws Exception {
                     ChannelPipeline p = ch.pipeline();
                     p.addLast(new LoggingHandler()); // Logging interceptor
                     p.addLast(new AuthenticationHandler()); // Authentication filter
                     p.addLast(new SimpleServerHandler()); // Main handler
                 }
             });

            b.bind(8080).sync().channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

2. 实现拦截器(LoggingHandler)

LoggingHandler是一个简单的拦截器,它在每次接收到消息时进行日志记录。

java 复制代码
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class LoggingHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("Received message: " + msg);
        super.channelRead(ctx, msg); // 继续传递消息给下一个处理器
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

3. 实现过滤器(AuthenticationHandler)

AuthenticationHandler是一个简单的过滤器,它在处理消息前进行认证检查。

java 复制代码
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class AuthenticationHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 假设 msg 是一个字符串,包含用户名和密码
        String message = (String) msg;
        if (authenticate(message)) {
            super.channelRead(ctx, msg); // 认证通过,继续传递消息给下一个处理器
        } else {
            ctx.writeAndFlush("Authentication failed");
            ctx.close();
        }
    }

    private boolean authenticate(String message) {
        // 简单的认证逻辑
        return "username:password".equals(message);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

4. 实现主处理器(SimpleServerHandler)

SimpleServerHandler是服务器的主要处理器,它处理经过认证的消息并返回响应。

java 复制代码
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class SimpleServerHandler extends SimpleChannelInboundHandler<String> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        System.out.println("Processing message: " + msg);
        ctx.writeAndFlush("Hello, " + msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

5. 定义客户端

定义一个简单的客户端来测试服务器。

java 复制代码
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class SimpleClient {
    public static void main(String[] args) throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
             .channel(NioSocketChannel.class)
             .handler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 protected void initChannel(SocketChannel ch) throws Exception {
                     ChannelPipeline p = ch.pipeline();
                     p.addLast(new StringDecoder());
                     p.addLast(new StringEncoder());
                     p.addLast(new SimpleClientHandler());
                 }
             });

            b.connect("localhost", 8080).sync().channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }
}

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class SimpleClientHandler extends SimpleChannelInboundHandler<String> {
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.writeAndFlush("username:password");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        System.out.println("Received response: " + msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

通过以上示例,您可以看到如何在Netty中使用拦截器和过滤器。拦截器和过滤器可以通过实现ChannelHandler接口并将其添加到ChannelPipeline中来实现。拦截器用于在处理请求和响应的某个阶段进行拦截,而过滤器则用于对数据进行过滤和修改。

相关推荐
一条Go3 小时前
OnCall 时段路由:跨午夜、左闭右开与「Local 不是时区」
后端·架构·github
Moment3 小时前
不会后期的我,发现了一个开源胶片神器😍😍😍
前端·后端·开源
数据库小学妹3 小时前
pgbouncer 事务池:prepared statement、临时表与会话状态
数据库·后端·postgresql
三小河4 小时前
SWC 凭什么比 Babel 快 ?项目优化迁移踩坑记录
前端·后端
鶴哥只手遮天4 小时前
《Redis 8.10.3 深度剖析》系列 ·第 17 章. 一个迟到十六年的类型
redis·后端·开源
知守观4 小时前
同一个团队两套分包:DDD 四层落地后,domain 层最大的类还是 5885 行
java·后端·领域驱动设计
Anymous5 小时前
我手写的 Redis 锁,输给了 10 秒的 TTL
后端·架构
Rain的Java大神之路5 小时前
设计一套生产级 API 接口:从契约、安全、幂等到限流,我踩过的坑都在这了
java·后端·面试
SimonKing5 小时前
零配置也能白嫖前沿大模型!dsh-our-free-model插件真香警告
java·后端·程序员
nice_lcj5205 小时前
【从零理解 Spring AI · 15】让检索更准:先宽召回,再精排序
java·后端·rag·spring ai·ai应用开发·检索优化·重排序