【六】Netty Google Protobuf 编解码

news2024/9/28 9:32:29

Netty Google Protobuf 编解码

  • Google Protobuf 介绍
  • Protobuf 的入门
    • Protobuf 开发环境搭建
      • Protobuf 下载
      • 创建.proto文件
        • 第五节的 对应实体(SubscribeReq,SubscribeResp )
        • SubscribeReq.proto 文件
        • SubscribeResp.proto
      • 利用命令生成对应的java文件
      • 测试下生成的java文件
        • 测试代码:
        • 运行效果截图:
  • Protobuf 版本的订购程序
    • 流程图
    • maven jar 依赖
    • 代码展示
      • 服务端启动类 SubscribeReqServer
      • 服务端业务处理类 SubscribeServerHandler
      • 客户端启动类 SubscribeClient
      • 客户端业务处理类 SubscribeClientHandler
      • 还有之前通过protoc.exe 生成的java 文件
        • SubscribeReq
        • SubscribeReqOrBuilder
        • SubscribeReqProto
        • SubscribeResp
        • SubscribeRespOrBuilder
        • SubscribeRespProto
    • 服务端客户端启动效果截图
      • 服务端打印
      • 客户端打印截图
  • Protobuf的使用注意事项
  • 总结

Google Protobuf 介绍

Google 的 Protobuf 在业界非常流行,很多商业项目选择Protobuf 作为编解码框架,Protobuf的优点如下:
(1)在谷歌内部长期使用,产品成熟度高;
(2)跨语言,支持多种语言,包括C++,Java和Python
(3)编码后的消息很小,更加有利于存储和传输
(4)编解码的性能非常高
(5)支持不同协议版本的向前兼容
(6)支持定义可选和必选字段

Protobuf 的入门

Protobuf 是一个灵活,高效,结构化的数据序列化框架,相比于XML等传统的序列化工具,它更小,更快,更简单。Protobuf 支持数据结构化一次可以到处使用,甚至跨语言使用,通过代码生成工具可以自动生成不同语言版本的源代码,甚至可以在使用不同版本的数据结构进程间进行数据传递,实现数据结构的向前兼容。

Protobuf 开发环境搭建

Protobuf 下载

Protobuf的2.5.0 版本下载地址:
1.在官网上面,找到 2.5.0 版本下载。
https://github.com/protocolbuffers/protobuf/releases?page=12
2.在csdn 界面下载
https://download.csdn.net/download/echohuangshihuxue/87374990
下载后解压如图:
在这里插入图片描述

创建.proto文件

我们基于 第五节(https://blog.csdn.net/echohuangshihuxue/article/details/128603624)
的 POJO SubscribeReq(订购请求实体)和SubscribeResp(订购应答实体) 来生成.proto文件。

第五节的 对应实体(SubscribeReq,SubscribeResp )

public class SubscribeReq implements Serializable {
    private static final long serialVersionUID=1L;
    //订购编号
    private int subReqID;
    //用户名
    private String userName;
    //订购的产品名称
    private String productName;
    //订购者的电话号码
    private String phoneNumber;
    //订购者的家庭地址
    private String address;


    public int getSubReqID() {
        return subReqID;
    }

    public void setSubReqID(int subReqID) {
        this.subReqID = subReqID;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String toString(){
        return "SubscribeReq [ subReqID = "+subReqID+" , userName = " +
                ""+userName+" , productName = "+productName+" ," +
                " phoneNumber = "+phoneNumber+" , address = "+address+" ]";
    }
}

public class SubscribeResp implements Serializable {
    private static final long serialVersionUID=1L;
    //订购编号
    private int subReqID;
    //订购结果 0 表示成功
    private int respCode;
    //可选的详细描述信息
    private String desc;

    public int getSubReqID() {
        return subReqID;
    }

    public void setSubReqID(int subReqID) {
        this.subReqID = subReqID;
    }

    public int getRespCode() {
        return respCode;
    }

    public void setRespCode(int respCode) {
        this.respCode = respCode;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String toString(){
        return "SubscribeResp [ subReqID = "+subReqID+" " +
                ", respCode = "+respCode+" , desc = "+desc+" ]";
    }
}

SubscribeReq.proto 文件

//定义协议类型
syntax="proto2";
//生成的Java文件的包名
package echo.cn;
//生成的Java文件的包名
option java_package ="echo.cn";
option java_multiple_files=true;
//生成的java 的类名
option java_outer_classname="SubscribeReqProto";


message SubscribeReq{
  required int32 subReqID = 1;
  required string userName=2;
  required string productName=3;
  required string phoneNumber=4;
  required string address=5;
}

SubscribeResp.proto

//协议类型
syntax="proto2";
package echo.cn;

option java_package ="echo.cn";
option java_multiple_files=true;
//生成的Java 文件的类名
option java_outer_classname="SubscribeRespProto";

message SubscribeResp{
  required int32 subReqID = 1;
  required int32 respCode=2;
  required string desc=3;
}

利用命令生成对应的java文件

将.proto文件和protoc.exe 放入同一个文件夹。然后在这个目录打开powerShell

在这里插入图片描述

然后在 当前目录的上级目录的src 目录下的echo.cn 目录下面就会生成对应的java文件。

在这里插入图片描述

测试下生成的java文件

写个简单的demo 验证下:

测试代码:

public class TestSubscribeReqProto {
    private static byte[] encode(SubscribeReq req){
        //SubscribeReq 能直接获取byte[],非常方便
        return req.toByteArray();
    }

    private static SubscribeReq decode(byte[]body) throws InvalidProtocolBufferException {
        //将二进制byte数组解码还原为原始的对象
        return SubscribeReq.parseFrom(body);
    }

    private static SubscribeReq createSubscribeReq(){
        //通过构建起对SubscribeReq的属性进行设置
        SubscribeReq.Builder builder=SubscribeReq.newBuilder();
        builder.setSubReqID(1);
        builder.setUserName("echo");
        builder.setProductName("netty learning protobuf");
        builder.setPhoneNumber("17748694444");
        builder.setAddress("shenzhen");
        return builder.build();
    }

    public static void main(String[] args) throws InvalidProtocolBufferException {
        SubscribeReq req=createSubscribeReq();
        System.out.println("Before encode(解码前) : "+req.toString());
        //先编码然后再解码,得到的对象和原始对象 equals比较。
        // 先编码再解码,模拟 不同进程 的工作,发送方 编码, 接收方解码。然后 得到的对象是否相等。
        // 如果相等,说明 protobuf 支持编解码
        SubscribeReq req1=decode(encode(req));
        System.out.println("After decode : "+req1.toString());
        System.out.println("Assert equal : --> "+req1.equals(req));
    }
}

运行效果截图:

在这里插入图片描述
好了,说明我们生成的java 文件是ok 的。接下来我们来依据protobuf 来实现编码解码的功能。

Protobuf 版本的订购程序

流程图

在这里插入图片描述

maven jar 依赖

          <!-- protobuf -->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>2.5.0</version>
        </dependency>
        <dependency>
            <groupId>com.googlecode.protobuf-java-format</groupId>
            <artifactId>protobuf-java-format</artifactId>
            <version>1.2</version>
        </dependency>

代码展示

服务端启动类 SubscribeReqServer

public class SubscribeReqServer {
    public void bind(int port){
        //配置服务端的NIO线程组
        EventLoopGroup parentGroup=new NioEventLoopGroup();
        EventLoopGroup childGroup=new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap=new ServerBootstrap();
            bootstrap.group(parentGroup,childGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG,100)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            // ProtobufVarint32FrameDecoder 主要用于半包处理
                         socketChannel.pipeline().addLast(
                                 new ProtobufVarint32FrameDecoder()
                         );
                         // ProtobufDecoder 的参数是 SubscribeReq,实际上就是要告诉
                            //ProtobufDecoder 需要解码的目标类是什么,否则仅仅从字节数组中是无法
                            //判断出需要解码的目标类型信息的。
                         socketChannel.pipeline()
                                         .addLast(new ProtobufDecoder(SubscribeReq.getDefaultInstance()));
                         socketChannel.pipeline()
                                         .addLast(new ProtobufVarint32LengthFieldPrepender());
                         socketChannel.pipeline()
                                         .addLast(new ProtobufEncoder());
                            socketChannel.pipeline()
                                    .addLast(new SubscribeServerHandler());
                        }
                    });
            //绑定端口,同步等待成功
            ChannelFuture future=bootstrap.bind(port).sync();
            System.out.println("netty server is started");
           // 等待服务器监听端口关闭
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //优雅退出,释放线程池资源
            parentGroup.shutdownGracefully();
            childGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        new SubscribeReqServer().bind(8080);
    }
}

服务端业务处理类 SubscribeServerHandler

public class SubscribeServerHandler extends ChannelHandlerAdapter {

    public void channelRead(ChannelHandlerContext context, Object obj){
        SubscribeReq subscribeReq=(SubscribeReq)obj;
        //对合法性进行交易,当前只校验userName属性。如果符合,将信息发送给客户端
        if ("echo".equals(subscribeReq.getUserName())){
            System.out.println("Service accept client subscribe req : "+subscribeReq);
            context.writeAndFlush(resp(subscribeReq.getSubReqID()));
        }
    }

    private SubscribeResp resp(int subId){
        //SubscribeResp subscribeResp=SubscribeResp.newBuilder().build();
        SubscribeResp.Builder builder=SubscribeResp.newBuilder();
        builder.setSubReqID(subId);
        builder.setRespCode(0);
        builder.setDesc("Netty learning is doing,please go on .");
        SubscribeResp subscribeResp=builder.build();
        System.out.println(subscribeResp);
        return subscribeResp;
    }

   public void exceptionCaught(ChannelHandlerContext context,Throwable throwable){
        throwable.printStackTrace();
        context.close();
    }


}

客户端启动类 SubscribeClient

public class SubscribeClient {

    private void connect(String host, int port) {
        EventLoopGroup workGroup = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(workGroup)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline()
                                            .addLast(new ProtobufVarint32FrameDecoder());
                            socketChannel.pipeline()
                                            .addLast(new ProtobufDecoder(SubscribeResp.getDefaultInstance()));
                            socketChannel.pipeline()
                                            .addLast(new ProtobufVarint32LengthFieldPrepender());
                            socketChannel.pipeline()
                                            .addLast(new ProtobufEncoder());
                            socketChannel.pipeline().addLast(new SubscribeClientHandler());

                        }
                    });
            ChannelFuture future=bootstrap.connect(host,port).sync();
            System.out.println("the netty client is started,and connected server");
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //优雅退出
            workGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        new SubscribeClient().connect("127.0.00.1",8080);
    }
}

客户端业务处理类 SubscribeClientHandler

public class SubscribeClientHandler extends ChannelHandlerAdapter {

    //tcp 链接成功后,就给服务端 循环发送10条信息
    public void channelActive(ChannelHandlerContext context){
        for (int i=0;i<10;i++){
            context.write(subReq(i));
        }
        context.flush();
    }

    private SubscribeReq subReq(int i){
        SubscribeReq.Builder builder=SubscribeReq.newBuilder();
        builder.setSubReqID(i);
        builder.setAddress("shen zhen xixiang dadao");
        builder.setPhoneNumber("174868xxxx");
        builder.setProductName("Netty learning ");
        builder.setUserName("echo");
        return  builder.build();
    }

    /**
     * 由于对象解码器已经对 SubscribeResp 请求消息 进行了自动解码,
     * 因此
     * @param context
     * @param obj
     */
    public void channelRead(ChannelHandlerContext context,Object obj){
       // System.out.println("hello ni hao ");
        System.out.println("Receive server response : "+obj);
    }

    public void channelReadComplete(ChannelHandlerContext context){
        context.flush();
    }



}

还有之前通过protoc.exe 生成的java 文件

SubscribeReq

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: SubscribeReq.proto

package echo.cn;

/**
 * Protobuf type {@code echo.cn.SubscribeReq}
 */
public  final class SubscribeReq extends
    com.google.protobuf.GeneratedMessage
    implements SubscribeReqOrBuilder {
  // Use SubscribeReq.newBuilder() to construct.
  private SubscribeReq(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
    super(builder);
    this.unknownFields = builder.getUnknownFields();
  }
  private SubscribeReq(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

  private static final SubscribeReq defaultInstance;
  public static SubscribeReq getDefaultInstance() {
    return defaultInstance;
  }

  public SubscribeReq getDefaultInstanceForType() {
    return defaultInstance;
  }

  private final com.google.protobuf.UnknownFieldSet unknownFields;
  @Override
  public final com.google.protobuf.UnknownFieldSet
      getUnknownFields() {
    return this.unknownFields;
  }
  private SubscribeReq(
      com.google.protobuf.CodedInputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    initFields();
    int mutable_bitField0_ = 0;
    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
        com.google.protobuf.UnknownFieldSet.newBuilder();
    try {
      boolean done = false;
      while (!done) {
        int tag = input.readTag();
        switch (tag) {
          case 0:
            done = true;
            break;
          default: {
            if (!parseUnknownField(input, unknownFields,
                                   extensionRegistry, tag)) {
              done = true;
            }
            break;
          }
          case 8: {
            bitField0_ |= 0x00000001;
            subReqID_ = input.readInt32();
            break;
          }
          case 18: {
            bitField0_ |= 0x00000002;
            userName_ = input.readBytes();
            break;
          }
          case 26: {
            bitField0_ |= 0x00000004;
            productName_ = input.readBytes();
            break;
          }
          case 34: {
            bitField0_ |= 0x00000008;
            phoneNumber_ = input.readBytes();
            break;
          }
          case 42: {
            bitField0_ |= 0x00000010;
            address_ = input.readBytes();
            break;
          }
        }
      }
    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
      throw e.setUnfinishedMessage(this);
    } catch (java.io.IOException e) {
      throw new com.google.protobuf.InvalidProtocolBufferException(
          e.getMessage()).setUnfinishedMessage(this);
    } finally {
      this.unknownFields = unknownFields.build();
      makeExtensionsImmutable();
    }
  }
  public static final com.google.protobuf.Descriptors.Descriptor
      getDescriptor() {
    return SubscribeReqProto.internal_static_echo_cn_SubscribeReq_descriptor;
  }

  protected FieldAccessorTable
      internalGetFieldAccessorTable() {
    return SubscribeReqProto.internal_static_echo_cn_SubscribeReq_fieldAccessorTable
        .ensureFieldAccessorsInitialized(
            SubscribeReq.class, Builder.class);
  }

  public static com.google.protobuf.Parser<SubscribeReq> PARSER =
      new com.google.protobuf.AbstractParser<SubscribeReq>() {
    public SubscribeReq parsePartialFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return new SubscribeReq(input, extensionRegistry);
    }
  };

  @Override
  public com.google.protobuf.Parser<SubscribeReq> getParserForType() {
    return PARSER;
  }

  private int bitField0_;
  // required int32 subReqID = 1;
  public static final int SUBREQID_FIELD_NUMBER = 1;
  private int subReqID_;
  /**
   * <code>required int32 subReqID = 1;</code>
   */
  public boolean hasSubReqID() {
    return ((bitField0_ & 0x00000001) == 0x00000001);
  }
  /**
   * <code>required int32 subReqID = 1;</code>
   */
  public int getSubReqID() {
    return subReqID_;
  }

  // required string userName = 2;
  public static final int USERNAME_FIELD_NUMBER = 2;
  private Object userName_;
  /**
   * <code>required string userName = 2;</code>
   */
  public boolean hasUserName() {
    return ((bitField0_ & 0x00000002) == 0x00000002);
  }
  /**
   * <code>required string userName = 2;</code>
   */
  public String getUserName() {
    Object ref = userName_;
    if (ref instanceof String) {
      return (String) ref;
    } else {
      com.google.protobuf.ByteString bs = 
          (com.google.protobuf.ByteString) ref;
      String s = bs.toStringUtf8();
      if (bs.isValidUtf8()) {
        userName_ = s;
      }
      return s;
    }
  }
  /**
   * <code>required string userName = 2;</code>
   */
  public com.google.protobuf.ByteString
      getUserNameBytes() {
    Object ref = userName_;
    if (ref instanceof String) {
      com.google.protobuf.ByteString b = 
          com.google.protobuf.ByteString.copyFromUtf8(
              (String) ref);
      userName_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }

  // required string productName = 3;
  public static final int PRODUCTNAME_FIELD_NUMBER = 3;
  private Object productName_;
  /**
   * <code>required string productName = 3;</code>
   */
  public boolean hasProductName() {
    return ((bitField0_ & 0x00000004) == 0x00000004);
  }
  /**
   * <code>required string productName = 3;</code>
   */
  public String getProductName() {
    Object ref = productName_;
    if (ref instanceof String) {
      return (String) ref;
    } else {
      com.google.protobuf.ByteString bs = 
          (com.google.protobuf.ByteString) ref;
      String s = bs.toStringUtf8();
      if (bs.isValidUtf8()) {
        productName_ = s;
      }
      return s;
    }
  }
  /**
   * <code>required string productName = 3;</code>
   */
  public com.google.protobuf.ByteString
      getProductNameBytes() {
    Object ref = productName_;
    if (ref instanceof String) {
      com.google.protobuf.ByteString b = 
          com.google.protobuf.ByteString.copyFromUtf8(
              (String) ref);
      productName_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }

  // required string phoneNumber = 4;
  public static final int PHONENUMBER_FIELD_NUMBER = 4;
  private Object phoneNumber_;
  /**
   * <code>required string phoneNumber = 4;</code>
   */
  public boolean hasPhoneNumber() {
    return ((bitField0_ & 0x00000008) == 0x00000008);
  }
  /**
   * <code>required string phoneNumber = 4;</code>
   */
  public String getPhoneNumber() {
    Object ref = phoneNumber_;
    if (ref instanceof String) {
      return (String) ref;
    } else {
      com.google.protobuf.ByteString bs = 
          (com.google.protobuf.ByteString) ref;
      String s = bs.toStringUtf8();
      if (bs.isValidUtf8()) {
        phoneNumber_ = s;
      }
      return s;
    }
  }
  /**
   * <code>required string phoneNumber = 4;</code>
   */
  public com.google.protobuf.ByteString
      getPhoneNumberBytes() {
    Object ref = phoneNumber_;
    if (ref instanceof String) {
      com.google.protobuf.ByteString b = 
          com.google.protobuf.ByteString.copyFromUtf8(
              (String) ref);
      phoneNumber_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }

  // required string address = 5;
  public static final int ADDRESS_FIELD_NUMBER = 5;
  private Object address_;
  /**
   * <code>required string address = 5;</code>
   */
  public boolean hasAddress() {
    return ((bitField0_ & 0x00000010) == 0x00000010);
  }
  /**
   * <code>required string address = 5;</code>
   */
  public String getAddress() {
    Object ref = address_;
    if (ref instanceof String) {
      return (String) ref;
    } else {
      com.google.protobuf.ByteString bs = 
          (com.google.protobuf.ByteString) ref;
      String s = bs.toStringUtf8();
      if (bs.isValidUtf8()) {
        address_ = s;
      }
      return s;
    }
  }
  /**
   * <code>required string address = 5;</code>
   */
  public com.google.protobuf.ByteString
      getAddressBytes() {
    Object ref = address_;
    if (ref instanceof String) {
      com.google.protobuf.ByteString b = 
          com.google.protobuf.ByteString.copyFromUtf8(
              (String) ref);
      address_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }

  private void initFields() {
    subReqID_ = 0;
    userName_ = "";
    productName_ = "";
    phoneNumber_ = "";
    address_ = "";
  }
  private byte memoizedIsInitialized = -1;
  public final boolean isInitialized() {
    byte isInitialized = memoizedIsInitialized;
    if (isInitialized != -1) return isInitialized == 1;

    if (!hasSubReqID()) {
      memoizedIsInitialized = 0;
      return false;
    }
    if (!hasUserName()) {
      memoizedIsInitialized = 0;
      return false;
    }
    if (!hasProductName()) {
      memoizedIsInitialized = 0;
      return false;
    }
    if (!hasPhoneNumber()) {
      memoizedIsInitialized = 0;
      return false;
    }
    if (!hasAddress()) {
      memoizedIsInitialized = 0;
      return false;
    }
    memoizedIsInitialized = 1;
    return true;
  }

  public void writeTo(com.google.protobuf.CodedOutputStream output)
                      throws java.io.IOException {
    getSerializedSize();
    if (((bitField0_ & 0x00000001) == 0x00000001)) {
      output.writeInt32(1, subReqID_);
    }
    if (((bitField0_ & 0x00000002) == 0x00000002)) {
      output.writeBytes(2, getUserNameBytes());
    }
    if (((bitField0_ & 0x00000004) == 0x00000004)) {
      output.writeBytes(3, getProductNameBytes());
    }
    if (((bitField0_ & 0x00000008) == 0x00000008)) {
      output.writeBytes(4, getPhoneNumberBytes());
    }
    if (((bitField0_ & 0x00000010) == 0x00000010)) {
      output.writeBytes(5, getAddressBytes());
    }
    getUnknownFields().writeTo(output);
  }

  private int memoizedSerializedSize = -1;
  public int getSerializedSize() {
    int size = memoizedSerializedSize;
    if (size != -1) return size;

    size = 0;
    if (((bitField0_ & 0x00000001) == 0x00000001)) {
      size += com.google.protobuf.CodedOutputStream
        .computeInt32Size(1, subReqID_);
    }
    if (((bitField0_ & 0x00000002) == 0x00000002)) {
      size += com.google.protobuf.CodedOutputStream
        .computeBytesSize(2, getUserNameBytes());
    }
    if (((bitField0_ & 0x00000004) == 0x00000004)) {
      size += com.google.protobuf.CodedOutputStream
        .computeBytesSize(3, getProductNameBytes());
    }
    if (((bitField0_ & 0x00000008) == 0x00000008)) {
      size += com.google.protobuf.CodedOutputStream
        .computeBytesSize(4, getPhoneNumberBytes());
    }
    if (((bitField0_ & 0x00000010) == 0x00000010)) {
      size += com.google.protobuf.CodedOutputStream
        .computeBytesSize(5, getAddressBytes());
    }
    size += getUnknownFields().getSerializedSize();
    memoizedSerializedSize = size;
    return size;
  }

  private static final long serialVersionUID = 0L;
  @Override
  protected Object writeReplace()
      throws java.io.ObjectStreamException {
    return super.writeReplace();
  }

  public static SubscribeReq parseFrom(
      com.google.protobuf.ByteString data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static SubscribeReq parseFrom(
      com.google.protobuf.ByteString data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static SubscribeReq parseFrom(byte[] data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static SubscribeReq parseFrom(
      byte[] data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static SubscribeReq parseFrom(java.io.InputStream input)
      throws java.io.IOException {
    return PARSER.parseFrom(input);
  }
  public static SubscribeReq parseFrom(
      java.io.InputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return PARSER.parseFrom(input, extensionRegistry);
  }
  public static SubscribeReq parseDelimitedFrom(java.io.InputStream input)
      throws java.io.IOException {
    return PARSER.parseDelimitedFrom(input);
  }
  public static SubscribeReq parseDelimitedFrom(
      java.io.InputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return PARSER.parseDelimitedFrom(input, extensionRegistry);
  }
  public static SubscribeReq parseFrom(
      com.google.protobuf.CodedInputStream input)
      throws java.io.IOException {
    return PARSER.parseFrom(input);
  }
  public static SubscribeReq parseFrom(
      com.google.protobuf.CodedInputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return PARSER.parseFrom(input, extensionRegistry);
  }

  public static Builder newBuilder() { return Builder.create(); }
  public Builder newBuilderForType() { return newBuilder(); }
  public static Builder newBuilder(SubscribeReq prototype) {
    return newBuilder().mergeFrom(prototype);
  }
  public Builder toBuilder() { return newBuilder(this); }

  @Override
  protected Builder newBuilderForType(
      BuilderParent parent) {
    Builder builder = new Builder(parent);
    return builder;
  }
  /**
   * Protobuf type {@code echo.cn.SubscribeReq}
   */
  public static final class Builder extends
      com.google.protobuf.GeneratedMessage.Builder<Builder>
     implements SubscribeReqOrBuilder {
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return SubscribeReqProto.internal_static_echo_cn_SubscribeReq_descriptor;
    }

    protected FieldAccessorTable
        internalGetFieldAccessorTable() {
      return SubscribeReqProto.internal_static_echo_cn_SubscribeReq_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              SubscribeReq.class, Builder.class);
    }

    // Construct using echo.cn.SubscribeReq.newBuilder()
    private Builder() {
      maybeForceBuilderInitialization();
    }

    private Builder(
        BuilderParent parent) {
      super(parent);
      maybeForceBuilderInitialization();
    }
    private void maybeForceBuilderInitialization() {
      if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
      }
    }
    private static Builder create() {
      return new Builder();
    }

    public Builder clear() {
      super.clear();
      subReqID_ = 0;
      bitField0_ = (bitField0_ & ~0x00000001);
      userName_ = "";
      bitField0_ = (bitField0_ & ~0x00000002);
      productName_ = "";
      bitField0_ = (bitField0_ & ~0x00000004);
      phoneNumber_ = "";
      bitField0_ = (bitField0_ & ~0x00000008);
      address_ = "";
      bitField0_ = (bitField0_ & ~0x00000010);
      return this;
    }

    public Builder clone() {
      return create().mergeFrom(buildPartial());
    }

    public com.google.protobuf.Descriptors.Descriptor
        getDescriptorForType() {
      return SubscribeReqProto.internal_static_echo_cn_SubscribeReq_descriptor;
    }

    public SubscribeReq getDefaultInstanceForType() {
      return SubscribeReq.getDefaultInstance();
    }

    public SubscribeReq build() {
      SubscribeReq result = buildPartial();
      if (!result.isInitialized()) {
        throw newUninitializedMessageException(result);
      }
      return result;
    }

    public SubscribeReq buildPartial() {
      SubscribeReq result = new SubscribeReq(this);
      int from_bitField0_ = bitField0_;
      int to_bitField0_ = 0;
      if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
        to_bitField0_ |= 0x00000001;
      }
      result.subReqID_ = subReqID_;
      if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
        to_bitField0_ |= 0x00000002;
      }
      result.userName_ = userName_;
      if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
        to_bitField0_ |= 0x00000004;
      }
      result.productName_ = productName_;
      if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
        to_bitField0_ |= 0x00000008;
      }
      result.phoneNumber_ = phoneNumber_;
      if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
        to_bitField0_ |= 0x00000010;
      }
      result.address_ = address_;
      result.bitField0_ = to_bitField0_;
      onBuilt();
      return result;
    }

    public Builder mergeFrom(com.google.protobuf.Message other) {
      if (other instanceof SubscribeReq) {
        return mergeFrom((SubscribeReq)other);
      } else {
        super.mergeFrom(other);
        return this;
      }
    }

    public Builder mergeFrom(SubscribeReq other) {
      if (other == SubscribeReq.getDefaultInstance()) return this;
      if (other.hasSubReqID()) {
        setSubReqID(other.getSubReqID());
      }
      if (other.hasUserName()) {
        bitField0_ |= 0x00000002;
        userName_ = other.userName_;
        onChanged();
      }
      if (other.hasProductName()) {
        bitField0_ |= 0x00000004;
        productName_ = other.productName_;
        onChanged();
      }
      if (other.hasPhoneNumber()) {
        bitField0_ |= 0x00000008;
        phoneNumber_ = other.phoneNumber_;
        onChanged();
      }
      if (other.hasAddress()) {
        bitField0_ |= 0x00000010;
        address_ = other.address_;
        onChanged();
      }
      this.mergeUnknownFields(other.getUnknownFields());
      return this;
    }

    public final boolean isInitialized() {
      if (!hasSubReqID()) {
        
        return false;
      }
      if (!hasUserName()) {
        
        return false;
      }
      if (!hasProductName()) {
        
        return false;
      }
      if (!hasPhoneNumber()) {
        
        return false;
      }
      if (!hasAddress()) {
        
        return false;
      }
      return true;
    }

    public Builder mergeFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      SubscribeReq parsedMessage = null;
      try {
        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        parsedMessage = (SubscribeReq) e.getUnfinishedMessage();
        throw e;
      } finally {
        if (parsedMessage != null) {
          mergeFrom(parsedMessage);
        }
      }
      return this;
    }
    private int bitField0_;

    // required int32 subReqID = 1;
    private int subReqID_ ;
    /**
     * <code>required int32 subReqID = 1;</code>
     */
    public boolean hasSubReqID() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 subReqID = 1;</code>
     */
    public int getSubReqID() {
      return subReqID_;
    }
    /**
     * <code>required int32 subReqID = 1;</code>
     */
    public Builder setSubReqID(int value) {
      bitField0_ |= 0x00000001;
      subReqID_ = value;
      onChanged();
      return this;
    }
    /**
     * <code>required int32 subReqID = 1;</code>
     */
    public Builder clearSubReqID() {
      bitField0_ = (bitField0_ & ~0x00000001);
      subReqID_ = 0;
      onChanged();
      return this;
    }

    // required string userName = 2;
    private Object userName_ = "";
    /**
     * <code>required string userName = 2;</code>
     */
    public boolean hasUserName() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required string userName = 2;</code>
     */
    public String getUserName() {
      Object ref = userName_;
      if (!(ref instanceof String)) {
        String s = ((com.google.protobuf.ByteString) ref)
            .toStringUtf8();
        userName_ = s;
        return s;
      } else {
        return (String) ref;
      }
    }
    /**
     * <code>required string userName = 2;</code>
     */
    public com.google.protobuf.ByteString
        getUserNameBytes() {
      Object ref = userName_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (String) ref);
        userName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>required string userName = 2;</code>
     */
    public Builder setUserName(
        String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
      userName_ = value;
      onChanged();
      return this;
    }
    /**
     * <code>required string userName = 2;</code>
     */
    public Builder clearUserName() {
      bitField0_ = (bitField0_ & ~0x00000002);
      userName_ = getDefaultInstance().getUserName();
      onChanged();
      return this;
    }
    /**
     * <code>required string userName = 2;</code>
     */
    public Builder setUserNameBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
      userName_ = value;
      onChanged();
      return this;
    }

    // required string productName = 3;
    private Object productName_ = "";
    /**
     * <code>required string productName = 3;</code>
     */
    public boolean hasProductName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required string productName = 3;</code>
     */
    public String getProductName() {
      Object ref = productName_;
      if (!(ref instanceof String)) {
        String s = ((com.google.protobuf.ByteString) ref)
            .toStringUtf8();
        productName_ = s;
        return s;
      } else {
        return (String) ref;
      }
    }
    /**
     * <code>required string productName = 3;</code>
     */
    public com.google.protobuf.ByteString
        getProductNameBytes() {
      Object ref = productName_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (String) ref);
        productName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>required string productName = 3;</code>
     */
    public Builder setProductName(
        String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
      productName_ = value;
      onChanged();
      return this;
    }
    /**
     * <code>required string productName = 3;</code>
     */
    public Builder clearProductName() {
      bitField0_ = (bitField0_ & ~0x00000004);
      productName_ = getDefaultInstance().getProductName();
      onChanged();
      return this;
    }
    /**
     * <code>required string productName = 3;</code>
     */
    public Builder setProductNameBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
      productName_ = value;
      onChanged();
      return this;
    }

    // required string phoneNumber = 4;
    private Object phoneNumber_ = "";
    /**
     * <code>required string phoneNumber = 4;</code>
     */
    public boolean hasPhoneNumber() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required string phoneNumber = 4;</code>
     */
    public String getPhoneNumber() {
      Object ref = phoneNumber_;
      if (!(ref instanceof String)) {
        String s = ((com.google.protobuf.ByteString) ref)
            .toStringUtf8();
        phoneNumber_ = s;
        return s;
      } else {
        return (String) ref;
      }
    }
    /**
     * <code>required string phoneNumber = 4;</code>
     */
    public com.google.protobuf.ByteString
        getPhoneNumberBytes() {
      Object ref = phoneNumber_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (String) ref);
        phoneNumber_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>required string phoneNumber = 4;</code>
     */
    public Builder setPhoneNumber(
        String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
      phoneNumber_ = value;
      onChanged();
      return this;
    }
    /**
     * <code>required string phoneNumber = 4;</code>
     */
    public Builder clearPhoneNumber() {
      bitField0_ = (bitField0_ & ~0x00000008);
      phoneNumber_ = getDefaultInstance().getPhoneNumber();
      onChanged();
      return this;
    }
    /**
     * <code>required string phoneNumber = 4;</code>
     */
    public Builder setPhoneNumberBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
      phoneNumber_ = value;
      onChanged();
      return this;
    }

    // required string address = 5;
    private Object address_ = "";
    /**
     * <code>required string address = 5;</code>
     */
    public boolean hasAddress() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>required string address = 5;</code>
     */
    public String getAddress() {
      Object ref = address_;
      if (!(ref instanceof String)) {
        String s = ((com.google.protobuf.ByteString) ref)
            .toStringUtf8();
        address_ = s;
        return s;
      } else {
        return (String) ref;
      }
    }
    /**
     * <code>required string address = 5;</code>
     */
    public com.google.protobuf.ByteString
        getAddressBytes() {
      Object ref = address_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (String) ref);
        address_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>required string address = 5;</code>
     */
    public Builder setAddress(
        String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
      address_ = value;
      onChanged();
      return this;
    }
    /**
     * <code>required string address = 5;</code>
     */
    public Builder clearAddress() {
      bitField0_ = (bitField0_ & ~0x00000010);
      address_ = getDefaultInstance().getAddress();
      onChanged();
      return this;
    }
    /**
     * <code>required string address = 5;</code>
     */
    public Builder setAddressBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
      address_ = value;
      onChanged();
      return this;
    }

    // @@protoc_insertion_point(builder_scope:echo.cn.SubscribeReq)
  }

  static {
    defaultInstance = new SubscribeReq(true);
    defaultInstance.initFields();
  }

  // @@protoc_insertion_point(class_scope:echo.cn.SubscribeReq)
}


SubscribeReqOrBuilder

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: SubscribeReq.proto

package echo.cn;

public interface SubscribeReqOrBuilder
    extends com.google.protobuf.MessageOrBuilder {

  // required int32 subReqID = 1;
  /**
   * <code>required int32 subReqID = 1;</code>
   */
  boolean hasSubReqID();
  /**
   * <code>required int32 subReqID = 1;</code>
   */
  int getSubReqID();

  // required string userName = 2;
  /**
   * <code>required string userName = 2;</code>
   */
  boolean hasUserName();
  /**
   * <code>required string userName = 2;</code>
   */
  String getUserName();
  /**
   * <code>required string userName = 2;</code>
   */
  com.google.protobuf.ByteString
      getUserNameBytes();

  // required string productName = 3;
  /**
   * <code>required string productName = 3;</code>
   */
  boolean hasProductName();
  /**
   * <code>required string productName = 3;</code>
   */
  String getProductName();
  /**
   * <code>required string productName = 3;</code>
   */
  com.google.protobuf.ByteString
      getProductNameBytes();

  // required string phoneNumber = 4;
  /**
   * <code>required string phoneNumber = 4;</code>
   */
  boolean hasPhoneNumber();
  /**
   * <code>required string phoneNumber = 4;</code>
   */
  String getPhoneNumber();
  /**
   * <code>required string phoneNumber = 4;</code>
   */
  com.google.protobuf.ByteString
      getPhoneNumberBytes();

  // required string address = 5;
  /**
   * <code>required string address = 5;</code>
   */
  boolean hasAddress();
  /**
   * <code>required string address = 5;</code>
   */
  String getAddress();
  /**
   * <code>required string address = 5;</code>
   */
  com.google.protobuf.ByteString
      getAddressBytes();
}

SubscribeReqProto

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: SubscribeReq.proto

package echo.cn;

public final class SubscribeReqProto {
  private SubscribeReqProto() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
  }
  static com.google.protobuf.Descriptors.Descriptor
    internal_static_echo_cn_SubscribeReq_descriptor;
  static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_echo_cn_SubscribeReq_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    String[] descriptorData = {
      "\n\022SubscribeReq.proto\022\007echo.cn\"m\n\014Subscri" +
      "beReq\022\020\n\010subReqID\030\001 \002(\005\022\020\n\010userName\030\002 \002(" +
      "\t\022\023\n\013productName\030\003 \002(\t\022\023\n\013phoneNumber\030\004 " +
      "\002(\t\022\017\n\007address\030\005 \002(\tB\036\n\007echo.cnB\021Subscri" +
      "beReqProtoP\001"
    };
    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
        public com.google.protobuf.ExtensionRegistry assignDescriptors(
            com.google.protobuf.Descriptors.FileDescriptor root) {
          descriptor = root;
          internal_static_echo_cn_SubscribeReq_descriptor =
            getDescriptor().getMessageTypes().get(0);
          internal_static_echo_cn_SubscribeReq_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_echo_cn_SubscribeReq_descriptor,
              new String[] { "SubReqID", "UserName", "ProductName", "PhoneNumber", "Address", });
          return null;
        }
      };
    com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        }, assigner);
  }

  // @@protoc_insertion_point(outer_class_scope)
}

SubscribeResp

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: SubscribeResp.proto

package echo.cn;

/**
 * Protobuf type {@code echo.cn.SubscribeResp}
 */
public  final class SubscribeResp extends
    com.google.protobuf.GeneratedMessage
    implements SubscribeRespOrBuilder {
  // Use SubscribeResp.newBuilder() to construct.
  private SubscribeResp(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
    super(builder);
    this.unknownFields = builder.getUnknownFields();
  }
  private SubscribeResp(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

  private static final SubscribeResp defaultInstance;
  public static SubscribeResp getDefaultInstance() {
    return defaultInstance;
  }

  public SubscribeResp getDefaultInstanceForType() {
    return defaultInstance;
  }

  private final com.google.protobuf.UnknownFieldSet unknownFields;
  @Override
  public final com.google.protobuf.UnknownFieldSet
      getUnknownFields() {
    return this.unknownFields;
  }
  private SubscribeResp(
      com.google.protobuf.CodedInputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    initFields();
    int mutable_bitField0_ = 0;
    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
        com.google.protobuf.UnknownFieldSet.newBuilder();
    try {
      boolean done = false;
      while (!done) {
        int tag = input.readTag();
        switch (tag) {
          case 0:
            done = true;
            break;
          default: {
            if (!parseUnknownField(input, unknownFields,
                                   extensionRegistry, tag)) {
              done = true;
            }
            break;
          }
          case 8: {
            bitField0_ |= 0x00000001;
            subReqID_ = input.readInt32();
            break;
          }
          case 16: {
            bitField0_ |= 0x00000002;
            respCode_ = input.readInt32();
            break;
          }
          case 26: {
            bitField0_ |= 0x00000004;
            desc_ = input.readBytes();
            break;
          }
        }
      }
    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
      throw e.setUnfinishedMessage(this);
    } catch (java.io.IOException e) {
      throw new com.google.protobuf.InvalidProtocolBufferException(
          e.getMessage()).setUnfinishedMessage(this);
    } finally {
      this.unknownFields = unknownFields.build();
      makeExtensionsImmutable();
    }
  }
  public static final com.google.protobuf.Descriptors.Descriptor
      getDescriptor() {
    return SubscribeRespProto.internal_static_echo_cn_SubscribeResp_descriptor;
  }

  protected FieldAccessorTable
      internalGetFieldAccessorTable() {
    return SubscribeRespProto.internal_static_echo_cn_SubscribeResp_fieldAccessorTable
        .ensureFieldAccessorsInitialized(
            SubscribeResp.class, Builder.class);
  }

  public static com.google.protobuf.Parser<SubscribeResp> PARSER =
      new com.google.protobuf.AbstractParser<SubscribeResp>() {
    public SubscribeResp parsePartialFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return new SubscribeResp(input, extensionRegistry);
    }
  };

  @Override
  public com.google.protobuf.Parser<SubscribeResp> getParserForType() {
    return PARSER;
  }

  private int bitField0_;
  // required int32 subReqID = 1;
  public static final int SUBREQID_FIELD_NUMBER = 1;
  private int subReqID_;
  /**
   * <code>required int32 subReqID = 1;</code>
   */
  public boolean hasSubReqID() {
    return ((bitField0_ & 0x00000001) == 0x00000001);
  }
  /**
   * <code>required int32 subReqID = 1;</code>
   */
  public int getSubReqID() {
    return subReqID_;
  }

  // required int32 respCode = 2;
  public static final int RESPCODE_FIELD_NUMBER = 2;
  private int respCode_;
  /**
   * <code>required int32 respCode = 2;</code>
   */
  public boolean hasRespCode() {
    return ((bitField0_ & 0x00000002) == 0x00000002);
  }
  /**
   * <code>required int32 respCode = 2;</code>
   */
  public int getRespCode() {
    return respCode_;
  }

  // required string desc = 3;
  public static final int DESC_FIELD_NUMBER = 3;
  private Object desc_;
  /**
   * <code>required string desc = 3;</code>
   */
  public boolean hasDesc() {
    return ((bitField0_ & 0x00000004) == 0x00000004);
  }
  /**
   * <code>required string desc = 3;</code>
   */
  public String getDesc() {
    Object ref = desc_;
    if (ref instanceof String) {
      return (String) ref;
    } else {
      com.google.protobuf.ByteString bs = 
          (com.google.protobuf.ByteString) ref;
      String s = bs.toStringUtf8();
      if (bs.isValidUtf8()) {
        desc_ = s;
      }
      return s;
    }
  }
  /**
   * <code>required string desc = 3;</code>
   */
  public com.google.protobuf.ByteString
      getDescBytes() {
    Object ref = desc_;
    if (ref instanceof String) {
      com.google.protobuf.ByteString b = 
          com.google.protobuf.ByteString.copyFromUtf8(
              (String) ref);
      desc_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }

  private void initFields() {
    subReqID_ = 0;
    respCode_ = 0;
    desc_ = "";
  }
  private byte memoizedIsInitialized = -1;
  public final boolean isInitialized() {
    byte isInitialized = memoizedIsInitialized;
    if (isInitialized != -1) return isInitialized == 1;

    if (!hasSubReqID()) {
      memoizedIsInitialized = 0;
      return false;
    }
    if (!hasRespCode()) {
      memoizedIsInitialized = 0;
      return false;
    }
    if (!hasDesc()) {
      memoizedIsInitialized = 0;
      return false;
    }
    memoizedIsInitialized = 1;
    return true;
  }

  public void writeTo(com.google.protobuf.CodedOutputStream output)
                      throws java.io.IOException {
    getSerializedSize();
    if (((bitField0_ & 0x00000001) == 0x00000001)) {
      output.writeInt32(1, subReqID_);
    }
    if (((bitField0_ & 0x00000002) == 0x00000002)) {
      output.writeInt32(2, respCode_);
    }
    if (((bitField0_ & 0x00000004) == 0x00000004)) {
      output.writeBytes(3, getDescBytes());
    }
    getUnknownFields().writeTo(output);
  }

  private int memoizedSerializedSize = -1;
  public int getSerializedSize() {
    int size = memoizedSerializedSize;
    if (size != -1) return size;

    size = 0;
    if (((bitField0_ & 0x00000001) == 0x00000001)) {
      size += com.google.protobuf.CodedOutputStream
        .computeInt32Size(1, subReqID_);
    }
    if (((bitField0_ & 0x00000002) == 0x00000002)) {
      size += com.google.protobuf.CodedOutputStream
        .computeInt32Size(2, respCode_);
    }
    if (((bitField0_ & 0x00000004) == 0x00000004)) {
      size += com.google.protobuf.CodedOutputStream
        .computeBytesSize(3, getDescBytes());
    }
    size += getUnknownFields().getSerializedSize();
    memoizedSerializedSize = size;
    return size;
  }

  private static final long serialVersionUID = 0L;
  @Override
  protected Object writeReplace()
      throws java.io.ObjectStreamException {
    return super.writeReplace();
  }

  public static SubscribeResp parseFrom(
      com.google.protobuf.ByteString data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static SubscribeResp parseFrom(
      com.google.protobuf.ByteString data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static SubscribeResp parseFrom(byte[] data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static SubscribeResp parseFrom(
      byte[] data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static SubscribeResp parseFrom(java.io.InputStream input)
      throws java.io.IOException {
    return PARSER.parseFrom(input);
  }
  public static SubscribeResp parseFrom(
      java.io.InputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return PARSER.parseFrom(input, extensionRegistry);
  }
  public static SubscribeResp parseDelimitedFrom(java.io.InputStream input)
      throws java.io.IOException {
    return PARSER.parseDelimitedFrom(input);
  }
  public static SubscribeResp parseDelimitedFrom(
      java.io.InputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return PARSER.parseDelimitedFrom(input, extensionRegistry);
  }
  public static SubscribeResp parseFrom(
      com.google.protobuf.CodedInputStream input)
      throws java.io.IOException {
    return PARSER.parseFrom(input);
  }
  public static SubscribeResp parseFrom(
      com.google.protobuf.CodedInputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return PARSER.parseFrom(input, extensionRegistry);
  }

  public static Builder newBuilder() { return Builder.create(); }
  public Builder newBuilderForType() { return newBuilder(); }
  public static Builder newBuilder(SubscribeResp prototype) {
    return newBuilder().mergeFrom(prototype);
  }
  public Builder toBuilder() { return newBuilder(this); }

  @Override
  protected Builder newBuilderForType(
      BuilderParent parent) {
    Builder builder = new Builder(parent);
    return builder;
  }
  /**
   * Protobuf type {@code echo.cn.SubscribeResp}
   */
  public static final class Builder extends
      com.google.protobuf.GeneratedMessage.Builder<Builder>
     implements SubscribeRespOrBuilder {
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return SubscribeRespProto.internal_static_echo_cn_SubscribeResp_descriptor;
    }

    protected FieldAccessorTable
        internalGetFieldAccessorTable() {
      return SubscribeRespProto.internal_static_echo_cn_SubscribeResp_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              SubscribeResp.class, Builder.class);
    }

    // Construct using echo.cn.SubscribeResp.newBuilder()
    private Builder() {
      maybeForceBuilderInitialization();
    }

    private Builder(
        BuilderParent parent) {
      super(parent);
      maybeForceBuilderInitialization();
    }
    private void maybeForceBuilderInitialization() {
      if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
      }
    }
    private static Builder create() {
      return new Builder();
    }

    public Builder clear() {
      super.clear();
      subReqID_ = 0;
      bitField0_ = (bitField0_ & ~0x00000001);
      respCode_ = 0;
      bitField0_ = (bitField0_ & ~0x00000002);
      desc_ = "";
      bitField0_ = (bitField0_ & ~0x00000004);
      return this;
    }

    public Builder clone() {
      return create().mergeFrom(buildPartial());
    }

    public com.google.protobuf.Descriptors.Descriptor
        getDescriptorForType() {
      return SubscribeRespProto.internal_static_echo_cn_SubscribeResp_descriptor;
    }

    public SubscribeResp getDefaultInstanceForType() {
      return SubscribeResp.getDefaultInstance();
    }

    public SubscribeResp build() {
      SubscribeResp result = buildPartial();
      if (!result.isInitialized()) {
        throw newUninitializedMessageException(result);
      }
      return result;
    }

    public SubscribeResp buildPartial() {
      SubscribeResp result = new SubscribeResp(this);
      int from_bitField0_ = bitField0_;
      int to_bitField0_ = 0;
      if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
        to_bitField0_ |= 0x00000001;
      }
      result.subReqID_ = subReqID_;
      if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
        to_bitField0_ |= 0x00000002;
      }
      result.respCode_ = respCode_;
      if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
        to_bitField0_ |= 0x00000004;
      }
      result.desc_ = desc_;
      result.bitField0_ = to_bitField0_;
      onBuilt();
      return result;
    }

    public Builder mergeFrom(com.google.protobuf.Message other) {
      if (other instanceof SubscribeResp) {
        return mergeFrom((SubscribeResp)other);
      } else {
        super.mergeFrom(other);
        return this;
      }
    }

    public Builder mergeFrom(SubscribeResp other) {
      if (other == SubscribeResp.getDefaultInstance()) return this;
      if (other.hasSubReqID()) {
        setSubReqID(other.getSubReqID());
      }
      if (other.hasRespCode()) {
        setRespCode(other.getRespCode());
      }
      if (other.hasDesc()) {
        bitField0_ |= 0x00000004;
        desc_ = other.desc_;
        onChanged();
      }
      this.mergeUnknownFields(other.getUnknownFields());
      return this;
    }

    public final boolean isInitialized() {
      if (!hasSubReqID()) {
        
        return false;
      }
      if (!hasRespCode()) {
        
        return false;
      }
      if (!hasDesc()) {
        
        return false;
      }
      return true;
    }

    public Builder mergeFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      SubscribeResp parsedMessage = null;
      try {
        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        parsedMessage = (SubscribeResp) e.getUnfinishedMessage();
        throw e;
      } finally {
        if (parsedMessage != null) {
          mergeFrom(parsedMessage);
        }
      }
      return this;
    }
    private int bitField0_;

    // required int32 subReqID = 1;
    private int subReqID_ ;
    /**
     * <code>required int32 subReqID = 1;</code>
     */
    public boolean hasSubReqID() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 subReqID = 1;</code>
     */
    public int getSubReqID() {
      return subReqID_;
    }
    /**
     * <code>required int32 subReqID = 1;</code>
     */
    public Builder setSubReqID(int value) {
      bitField0_ |= 0x00000001;
      subReqID_ = value;
      onChanged();
      return this;
    }
    /**
     * <code>required int32 subReqID = 1;</code>
     */
    public Builder clearSubReqID() {
      bitField0_ = (bitField0_ & ~0x00000001);
      subReqID_ = 0;
      onChanged();
      return this;
    }

    // required int32 respCode = 2;
    private int respCode_ ;
    /**
     * <code>required int32 respCode = 2;</code>
     */
    public boolean hasRespCode() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int32 respCode = 2;</code>
     */
    public int getRespCode() {
      return respCode_;
    }
    /**
     * <code>required int32 respCode = 2;</code>
     */
    public Builder setRespCode(int value) {
      bitField0_ |= 0x00000002;
      respCode_ = value;
      onChanged();
      return this;
    }
    /**
     * <code>required int32 respCode = 2;</code>
     */
    public Builder clearRespCode() {
      bitField0_ = (bitField0_ & ~0x00000002);
      respCode_ = 0;
      onChanged();
      return this;
    }

    // required string desc = 3;
    private Object desc_ = "";
    /**
     * <code>required string desc = 3;</code>
     */
    public boolean hasDesc() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required string desc = 3;</code>
     */
    public String getDesc() {
      Object ref = desc_;
      if (!(ref instanceof String)) {
        String s = ((com.google.protobuf.ByteString) ref)
            .toStringUtf8();
        desc_ = s;
        return s;
      } else {
        return (String) ref;
      }
    }
    /**
     * <code>required string desc = 3;</code>
     */
    public com.google.protobuf.ByteString
        getDescBytes() {
      Object ref = desc_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (String) ref);
        desc_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>required string desc = 3;</code>
     */
    public Builder setDesc(
        String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
      desc_ = value;
      onChanged();
      return this;
    }
    /**
     * <code>required string desc = 3;</code>
     */
    public Builder clearDesc() {
      bitField0_ = (bitField0_ & ~0x00000004);
      desc_ = getDefaultInstance().getDesc();
      onChanged();
      return this;
    }
    /**
     * <code>required string desc = 3;</code>
     */
    public Builder setDescBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
      desc_ = value;
      onChanged();
      return this;
    }

    // @@protoc_insertion_point(builder_scope:echo.cn.SubscribeResp)
  }

  static {
    defaultInstance = new SubscribeResp(true);
    defaultInstance.initFields();
  }

  // @@protoc_insertion_point(class_scope:echo.cn.SubscribeResp)
}


SubscribeRespOrBuilder

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: SubscribeResp.proto

package echo.cn;

public interface SubscribeRespOrBuilder
    extends com.google.protobuf.MessageOrBuilder {

  // required int32 subReqID = 1;
  /**
   * <code>required int32 subReqID = 1;</code>
   */
  boolean hasSubReqID();
  /**
   * <code>required int32 subReqID = 1;</code>
   */
  int getSubReqID();

  // required int32 respCode = 2;
  /**
   * <code>required int32 respCode = 2;</code>
   */
  boolean hasRespCode();
  /**
   * <code>required int32 respCode = 2;</code>
   */
  int getRespCode();

  // required string desc = 3;
  /**
   * <code>required string desc = 3;</code>
   */
  boolean hasDesc();
  /**
   * <code>required string desc = 3;</code>
   */
  String getDesc();
  /**
   * <code>required string desc = 3;</code>
   */
  com.google.protobuf.ByteString
      getDescBytes();
}

SubscribeRespProto

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: SubscribeResp.proto

package echo.cn;

public final class SubscribeRespProto {
  private SubscribeRespProto() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
  }
  static com.google.protobuf.Descriptors.Descriptor
    internal_static_echo_cn_SubscribeResp_descriptor;
  static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_echo_cn_SubscribeResp_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    String[] descriptorData = {
      "\n\023SubscribeResp.proto\022\007echo.cn\"A\n\rSubscr" +
      "ibeResp\022\020\n\010subReqID\030\001 \002(\005\022\020\n\010respCode\030\002 " +
      "\002(\005\022\014\n\004desc\030\003 \002(\tB\037\n\007echo.cnB\022SubscribeR" +
      "espProtoP\001"
    };
    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
        public com.google.protobuf.ExtensionRegistry assignDescriptors(
            com.google.protobuf.Descriptors.FileDescriptor root) {
          descriptor = root;
          internal_static_echo_cn_SubscribeResp_descriptor =
            getDescriptor().getMessageTypes().get(0);
          internal_static_echo_cn_SubscribeResp_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_echo_cn_SubscribeResp_descriptor,
              new String[] { "SubReqID", "RespCode", "Desc", });
          return null;
        }
      };
    com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        }, assigner);
  }

  // @@protoc_insertion_point(outer_class_scope)
}

服务端客户端启动效果截图

服务端打印

在这里插入图片描述

客户端打印截图

在这里插入图片描述

Protobuf的使用注意事项

ProtobufDecoder 仅仅负责解码,它不支持读半包。因此 在 ProtobufDecoder 前面,一定要有能够处理读半包的解码器。有三种选择:
(1)使用Netty提供的ProtobufVarint32FrameDecoder
(2)继承Netty 提供的通用半包解码器 LengthFieldBaseedFrameDecoder
(3)继承ByteToMessageDecoder类,自定义半包处理逻辑。
读者可以注释掉 服务端启动类的 ProtobufVarint32FrameDecoder.会发现问题。
在这里插入图片描述

总结

首先在Protobuf的入门知识中,通过简单的样例代码熟悉如何用Protobuf对POJO对象进行编码。利用protoc.exe 编译.proto文件可能对于不熟悉的同学比较难,需要多实操几次。在掌握了Protobuf的基础知识之后,讲解如何使用Netty 的Protobuf进行客户端和服务端开发,最后对Protobuf解码器需要注意点进行了说明。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/150601.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

详解c++---string模拟实现

这里写目录标题前言准备工作构造函数析构函数迭代器的实现插入数据有关的函数实现reservepush_backoperatorappendinserterasefindresize[ ]clear>>>>新式拷贝构造函数新式赋值重载前言 在前面的文章里我们学习了c中string的用法&#xff0c;那么这篇文章我们将带…

Vue的双向绑定(数据劫持)

双向绑定所谓的双向绑定其实就是&#xff0c;ui或者数据有一方做了修改&#xff0c;那么另外一个也会随着改变。简单来说&#xff0c;视图驱动数据&#xff0c;同时数据也能驱动视图。视图驱动数据&#xff0c;只需要绑定事件。数据驱动视图&#xff0c;则需要去对数据做监听&a…

DC-DC PCB layout经验-含走线宽度和载流量表格

在DC-DC芯片的应用设计中&#xff0c;PCB布板是否合理对于芯片能否表现出其最优性能有着至关重要的影响。不合理的PCB布板会造成芯片性能变差如线性度下降&#xff08;包括输入线性度以及输出线性度&#xff09;、带载能力下降、工作不稳定、EMI辐射增加、输出噪声增加等&#…

不同Nodejs版本的TypeScript的建议配置

Node Target Mapping microsoft/TypeScript Wiki GitHubTypeScript is a superset of JavaScript that compiles to clean JavaScript output. - Node Target Mapping microsoft/TypeScript Wikihttps://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping以上是tsc…

SpringBoot+Vue项目知识管理系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏…

macOS 安装 Frama-C 及使用

操作系统&#xff1a;macOS 12.6 Monterey 官网安装指导&#xff1a;Get Frama-C 一、操作与避坑 &#x1f573;️ 1、macOS 包管理绕不开 Homebrew 工具&#xff0c;确保安装好。 2、安装 Frama-C 的必要依赖 brew install opam gmp gtk gtksourceview libgnomecanvas在安装…

MATLAB-最大值与最小值

在MATLAB中&#xff0c;用于计算最大值的函数是max函数&#xff0c;用于计算最小值的函数是min函数&#xff0c;其调用格式如下。Bmax(A) %计算最大值 &#xff0c;若A为向量&#xff0c;则计算并返回向量中的最大值;若A为矩阵&#xff0c;则计算并返回%一个含有各列最大值的行…

从0到1完成一个Vue后台管理项目(九、引入Breadcrumb面包屑,更改bug)

往期 从0到1完成一个Vue后台管理项目&#xff08;一、创建项目&#xff09; 从0到1完成一个Vue后台管理项目&#xff08;二、使用element-ui&#xff09; 从0到1完成一个Vue后台管理项目&#xff08;三、使用SCSS/LESS&#xff0c;安装图标库&#xff09; 从0到1完成一个Vu…

ansible(第四天)

三&#xff1a;编写playbook 1.Ansible playbook 临时命令可以作为一次性对一组主机运行简单的任务。不过&#xff0c;若要真正发挥Ansible的力量&#xff0c;需要了解如 何使用playbook可以轻松重复的方式对一组主机执行多项复杂的任务。 play是针对对清单中选定的主机运行…

汽车电子系统网络安全组织管理

声明 本文是学习GB-T 38628-2020 信息安全技术 汽车电子系统网络安全指南. 下载地址 http://github5.com/view/764而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 汽车电子系统网络安全组织管理 6.1 组织机构设置 组织应高度重视网络安全&#xff0c…

基于Prometheus+Grafana搭建监控平台(Windows/Linux环境exporter部署)

1. 介绍 1.1 Prometheus是什么?Prometheus&#xff08;普罗米修斯&#xff09;是一个最初在SoundCloud上构建的监控系统。自2012年成为社区开源项目&#xff0c;拥有非常活跃的开发人员和用户社区。为强调开源及独立维护&#xff0c;Prometheus于2016年加入云原生云计算基金会…

【从零开始学习深度学习】43. 算法优化之Adam算法【RMSProp算法与动量法的结合】介绍及其Pytorch实现

Adam算法是在RMSProp算法基础上对小批量随机梯度也做了指数加权移动平均 【可以看做是RMSProp算法与动量法的结合】。 目录1. Adam算法介绍2. 从零实现Adam算法3. Pytorch简洁实现Adam算法--optim.Adam总结1. Adam算法介绍 Adam算法使用了动量变量vt\boldsymbol{v}_tvt​和RMS…

LVGL官方UI设计软件——SquareLine Studio micropython 使用简单测评

经常去LVGL官网逛的人一定都知道这个软件&#xff0c;作为官方的亲儿子&#xff0c;使用体验如何呢&#xff0c;我简单体验了一周左右&#xff0c;简单做个测评&#xff0c;本测评仅代表我个人意见&#xff0c;并且仅限micropython的使用体验&#xff01; 首先是价格&#xff0…

TCP报文段(segment)首部格式

TCP传给IP的数据单元称作TCP报文段或简称为TCP段&#xff08;TCP segment&#xff09;。 IP传给链路层的数据单元称作IP数据报(IP datagram)。 通过以太网传输的比特流称作帧(Frame)。 逐层封装&#xff1a; 源端口号发送端端口号&#xff0c;字段长16位&#xff08;2字节&…

计算机网络第二章

物理层的基本概念物理层的作用&#xff1a;物理层解决如何在连接各种计算机的传输媒体上传输数据比特流&#xff0c;而不是指具体的传输媒体。物理层的主要任务&#xff1a;确定与传输媒体接口有关的一些特性 &#x1f51c;本质&#xff1a;定义一些固定标准物理层的四大特性&a…

Word怎么转PDF?8个Word转PDF工具分析

Word 到 PDF 转换工具是用于将 Microsoft Word&#xff08;DOC 或 DOCX&#xff09;文档转换为 PDF 格式的程序。根据操作模式&#xff0c;它可以是在线或离线软件。当然&#xff0c;考虑到市场上充斥着此类工具&#xff0c;获得最好的 DOCX 到 PDF 转换器可能会让人头疼。正是…

MySQL基础篇第12章(MySQL数据类型)

1. MySQL中的数据类型 常见的数据类型的属性&#xff1a; 2. 整数介绍 2.1 类型介绍 整数类型一共有 5 种&#xff0c;包括 TINYINT、SMALLINT、MEDIUMINT、INT&#xff08;INTEGER&#xff09;和 BIGINT。 它们的区别如下表所示&#xff1a; 2.2 可选属性 整数类型的可选…

javaweb-异步请求AjaxaxiosJSON

1&#xff0c;Ajax 1.1 概述 AJAX (Asynchronous JavaScript And XML)&#xff1a;异步的 JavaScript 和 XML。 我们先来说概念中的 JavaScript 和 XML&#xff0c;JavaScript 表明该技术和前端相关&#xff1b;XML 是指以此进行数据交换。而这两个我们之前都学习过。 ####…

JavaWeb基础——从入门到超神(笔记,持续更新)

day00综述 需要学习SpringBoot&#xff0c;但是JavaWeb是基础&#xff0c;来补一下 JavaWeb就是将数据库中的数据用好看的样式在网页上呈现出来 day01MySQL基础 接下来就是MySQL的安装什么的 mysqld --initialize-insecure mysqld -install net start mysql至此我的电脑上已…

【蓝桥杯-筑基篇】基础入门

&#x1f353;系列专栏:蓝桥杯 &#x1f349;个人主页:个人主页 目录 1.数位翻转 2.三个数求最大值的写法 3.两数交换的几种方法 4.身份证第18位合法性校验 5.黑洞数&#xff08;陷阱数&#xff09; 1.数位翻转 如: 整数 12345 返回结果为整数: 54321 当第一次看到这个题…