Netty を使用して、一般的な redis クライアントを記述します (任意の redis に接続するためのサーバー アドレスとポート番号を指定できます)。

技術アーキテクチャ

  1. java11
  2. netty 4.1.79.Final
  3. redis通信プロトコル

Netty を使用しているため、プロジェクトは Maven プロジェクトです。

Maven 依存関係 (pom.xml)

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.79.Final</version>
        </dependency>

Maven プロジェクトのパッケージ構成 (pom.xml ファイルにもあります)

<build>
        <finalName>Redis_Cli</finalName><!-- 导出jar的名字 -->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<!--                                    指定启动类的全限定名-->
                                    <mainClass>cn.xjt.NettyToRedis</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

netty を使用して redis サーバーに接続し、すべてのコードを通信します

package cn.xjt;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

/**
 * @author xujiangtao
 * @version 1.0
 * @description 使用netty框架利用redis协议操作redis
 * @date 2022/7/31 17:03
 */
public class NettyToRedis {
    
    

    /**
     * redis规定协议
     * *3 3:代表通过空格分割。有几个关键词及参数
     * 换行
     * $3 3:代表以下第一个关键词占几个字节(3个)
     * 换行
     * set
     * 换行
     * $4 4:同上
     * 换行
     * name
     * $8 8:同上
     * testname
     *
     *
     * 所以普通的一条命令 set name testname 被按照以上固定协议则如下:
     * *3
     * $3
     * set
     * $4
     * name
     * $8
     * testname
     */

    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入redis服务器地址(回车直接本地服务器:localhost)");
        String hostname = scanner.nextLine();
        if (hostname.equals("")){
    
    
            hostname = "localhost";
        }
        int port;
        System.out.println("请输入redis端口(回车直接端口默认:6379)");
        while (true){
    
    
            try {
    
    
                String str = scanner.nextLine();
                if (str.equals("")){
    
    
                    port = 6379;
                }else {
    
    
                    port = Integer.parseInt(scanner.nextLine());
                }
                break;
            }catch (NumberFormatException e){
    
    
                System.out.println("请输入合法端口:"+e.getMessage());
            }
        }
        NioEventLoopGroup boss = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap()
                .group(boss)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
    
    
                    @Override
                    protected void initChannel(NioSocketChannel channel){
    
    
                        Scanner sc = new Scanner(System.in);
                        channel.pipeline().addLast(new ChannelInboundHandlerAdapter(){
    
    
                            @Override
                            public void channelActive(ChannelHandlerContext ctx) {
    
    
                                System.out.println("连接成功,请输入redis的命令指令");
                                String commend = sc.nextLine();
                                sendCommend(ctx, commend.trim());
                            }
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) {
    
    
                                ByteBuf byteBuf = (ByteBuf) msg;
                                String resp = byteBuf.toString(StandardCharsets.UTF_8);
//                                System.out.println("正常响应:"+resp);
                                resp = resp.replace("\r\n","")
                                        .replace("+", "")
                                        .replace("$-1", "");
                                if (resp.contains("$")){
    
    
                                    resp = resp.substring(2);
                                }
                                System.out.println(resp);
                                if (resp.equals("-NOAUTH Authentication required.")){
    
    
                                    System.out.println("监测到连接该redis没有验证密码,请输入密码验证:");
                                    String password = sc.nextLine();
                                    String verifyCommend = "auth "+password;
                                    sendCommend(ctx, verifyCommend);
                                }else {
    
    
                                    String commend = sc.nextLine();
                                    sendCommend(ctx, commend.trim());
                                }
                            }
                        });
                    }
                });
        try {
    
    
            ChannelFuture connect = bootstrap.connect(new InetSocketAddress(hostname, port)).sync();
            connect.channel().closeFuture().sync();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            boss.shutdownGracefully();
        }
    }

    private static void sendCommend(ChannelHandlerContext ctx, String commend) {
    
    
        //        空格+换行
        final byte[] LINE = {
    
    13,10};
        if (commend.equals("q")){
    
    
            System.out.println("正在退出程序...");
            ctx.close();
        }
        List<String> words = Arrays.asList(commend.split(" "));
        ByteBuf buffer = ctx.alloc().buffer();
        buffer.writeBytes(("*" + words.size()).getBytes(StandardCharsets.UTF_8));
        buffer.writeBytes(LINE);
        for (String word : words) {
    
    
//            判断是不是中文汉字,如果是汉字,则每个汉字在utf-8 编码中占三个字节
            if (checkChinese(word)){
    
    
//                所以每个汉字的字节数*3
                buffer.writeBytes(("$" + word.length()*3).getBytes(StandardCharsets.UTF_8));
            }else {
    
    
                buffer.writeBytes(("$" + word.length()).getBytes(StandardCharsets.UTF_8));
            }
            buffer.writeBytes(LINE);
            buffer.writeBytes(word.getBytes(StandardCharsets.UTF_8));
            buffer.writeBytes(LINE);
        }
        ctx.writeAndFlush(buffer);
    }

    public static boolean checkChinese(String name)
    {
    
    
        int n;
        for(int i = 0; i < name.length(); i++) {
    
    
            n = name.charAt(i);
            if(!(19968 <= n && n <40869)) {
    
    
                return false;
            }
        }
        return true;
    }
}

使い方

1. 自分でプロジェクトをビルドし、jar パッケージをパックして、jar パッケージの操作を実行する (またはアイデアで直接開始する) 2.
または、パッケージ化された jar パッケージを直接ダウンロードする (java -jarターミナルでコマンドを使用して開始する)

jar パッケージのダウンロード先

redis_cli 一般的なクライアント jar パッケージのダウンロード アドレス

ファイルのダウンロードアドレス (上記のジャンプが無効な場合は、以下のリンクをコピーしてダウンロードできます)
http://xjtool.top:81/xjtfile/Redis_Cli.jar

効果は次のとおりです: (プログラムを終了するためのコマンド q)

ここに画像の説明を挿入
medis (redis クライアント ツール) を使用して確認します。コマンドも有効

エピローグ

1. ご不明な点がございましたら、ガイドをお願いします。同時に、学生は技術交流に参加することもできます。❤️
2.改善が必要な分野がある場合は、ディスカッションに参加することもできます。

おすすめ

転載: blog.csdn.net/languageStudent/article/details/126096545