手写JAVA代码实现与redis传输数据

一、需求背景

1.背景介绍

上一章**Redis简介、使用**中,讲述了redis服务端的Windows版本安装,以及Java客户端Jedis的使用。
引入Redis提供的客户端依赖就可实现和Redis服务端实现数据传输

2.需求简介

在不引入依赖的情况下,自己通过Java代码实现和Redis服务端实现数据传输

二、需求分析

1.需求拆解

想和Redis服务端进行数据传输
a.首先需要连接服务器(传输层)
b.传输的数据以字节、接口协议的方式进行,那么就需要将用户输入的数据转化为需要的数据格式(数据处理层)
c.为了方便使用者完成以上动作,提供相应的实现方法(操作层)

2.难点解析

a.获取传输给服务器的数据格式

传输的数据以字节、接口协议的方式进行。那么是以何种方式进行呢?
我们可以利用Java创建一个伪服务器,然后通过Jedis提供的set方法向伪服务器放数据

public static void main(String[] args) throws IOException {
		//创建本机端口6379的服务器
        ServerSocket serverSocket = new ServerSocket(6379);
        Socket socket = serverSocket.accept();
        //获取写进服务器的数据
        InputStream inputStream = socket.getInputStream();
        byte b[] = new byte[1024];
        inputStream.read(b);
        System.out.println(new String(b));
    }

启动上面的方法,开启伪服务器

import redis.clients.jedis.Jedis;

public class App {
    public static void main(String[] args) {
    	//向本机建立的伪服务器放入数据
        Jedis jedis = new Jedis("localhost",6379);
        jedis.set("foo", "bar");
        String value = jedis.get("foo");
        System.out.println("取得值为:"+value);
    }
}

执行上面的客户端方法,发送数据。查看伪服务器端控制台,结果如下:
在这里插入图片描述

由此看出,set(“foo”, “bar”)实际上传给服务端的数据如上样式。

b.解析数据协议

协议规则可查看Redis官网https://redis.io/topics/protocol
在这里插入图片描述
上面示例中传给服务器的第一行为:*3(根据官网描述,*在第一个字节则表示数组,*3表示数组个数为3。[$3,SET]、[$3,foo]、[$3,bar])
第二行:$3( $在第一个字节则表示字符,$3则表示有三个字节:S E T )
第三行:SET(就是执行set操作)
后面依次类推
而每一行在什么时候结尾(结尾标记)。由上面截图中最后一句英文可以看出"\r\n"代表一行结束

三、搭建框架

1.流程图解

在这里插入图片描述

2.逻辑梳理

流程图如上所示:
1.用户创建操作层中Jedis对象,通过构造方法将IP、端口传入
2.Jedis的有参构造方法中创建传输层的Connection对象,将IP、端口数值放入connection对象中
3.用户调用操作层的Jedis类提供的set、get方法进行操作
4.操作层的Jedis类提供的set、get方法调用传输层中的sendCommand方法,方法中先调用Connection类中提供的connect方法,进行连接redis服务器
5.sendCommand方法再调用数据处理层类Protocol中sendCommand方法,处理数据
6.将处理好的数据,传输给redis

四、代码实现

/**
 * 提供操作方法
 */
public class Jedis {
    private Connection connection;

    public Jedis(String ip, int port) {
        connection = new Connection(ip, port);
    }

    public String set(final String key,final String value){
        connection.sendCommand(Protocol.Command.SET,key.getBytes(),value.getBytes());
        return "";
    }
    public String get(final String key){
        return connection.sendCommand(Protocol.Command.GET,key.getBytes()).getReply();
    }
}
/**
 * 协议
 */
public class Protocol {

    private static final String X = "*";
    private static final String D = "$";
    private static final String K = "\r\n";
    /**
     * 组装发送信息
     * @param command
     * @param outputStream
     * @param b
     */
    public static  void sendCommand(Protocol.Command command,OutputStream outputStream,byte[] ...b){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(X).append(b.length+1).append(K);//*3
        stringBuffer.append(D).append(command.name().length()).append(K);//$3
        stringBuffer.append(command).append(K);
        for(byte []bytes:b){
            stringBuffer.append(D).append(bytes.length).append(K);
            stringBuffer.append(new String(bytes)).append(K);
        }
        try {
            System.out.println(stringBuffer.toString());
            outputStream.write(stringBuffer.toString().getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static enum Command{
        SET,GET
    }
}
public class Connection {
    private Socket socket;
    private String ip;
    private int port;
    private OutputStream outputStream;
    private InputStream inputStream;

    public Connection(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }
    public String getReply(){
        byte b[] = new byte[1024];
        try {
            socket.getInputStream().read(b);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new String(b);
    }

    public Connection sendCommand(Protocol.Command command,byte[] ...b){
        //连接
        connect();
        //发送
        Protocol.sendCommand(command,outputStream,b);
        return this;
    }

    private void connect() {
        try {
            socket = new Socket(ip, port);
            outputStream = socket.getOutputStream();
            inputStream = socket.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值