一块儿来学Netty - 序列化

在作 JAVA开发的时候,接触最多的就是 java.io.Serializable,经过该接口生成序列化ID,而后就能够经过 java.io.ObjectInput与 java.io.ObjectOutput进行序列化与反序列化,无需考虑跨语言调用,对序列化性能要求不高的状况,使用默认的是最方便的,虽然存在弊端,但也能知足大部分的须要....java

为了更好的掌握 Netty序列化相关知识,本章使用 Netty给咱们提供的 ObjectEncoder与 ObjectDecoder对订单请求与应答消息进行序列化操做...git

开发例程

  • 在服务端 ChannelPipeline新增解码器 io.netty.handler.codec.serialization.ObjectDecoder微信

  • 在服务端 ChannelPipeline新增解码器 io.netty.handler.codec.serialization.ObjectEncoderide

  • 实体类实现 java.io.Serializable序列化接口性能

1.建立 OrderRequest 与 OrderResponse两个 Javaflex

  
    
  
  
   
   
            
   
   
  1. this

  2. 编码

  3. spa

  4. .net

public class OrderRequest implements java.io.Serializable {    private static final long serialVersionUID = 1826067782744144943L;    private Integer orderId;    private String userName;    private String productName;    private String phoneNumber;    private String address;    //省略 get set ..}
  
    
  
  
   
   
            
   
   
public class OrderResponse implements java.io.Serializable {    private static final long serialVersionUID = -5003946216600820264L;    private Integer orderId;    private String respCode;    private String desc;}

OrderServer

1.重写 ChannelInitializer中的 initChannel方法,添加 ObjectDecoder解码器与 ObjectEncoder编码器

  
    
  
  
   
   
            
   
   
@Overrideprotected void initChannel(SocketChannel channel) throws Exception {    channel.pipeline().addLast(new ObjectDecoder(1024 * 1024, ClassResolvers.weakCachingResolver(this.getClass().getClassLoader())));    channel.pipeline().addLast(new ObjectEncoder());    channel.pipeline().addLast(new OrderServerHandler());}

注意 ObjectDecoder(intmaxObjectSize,ClassResolverclassResolver),第一个参数是设置序列化对象的最大字节长度,若是超出限定范围会抛出 StreamCorruptedException,默认(1024 * 1024 = 1048576字节),第二个参数用于作 类解码操做

2.建立 OrderServerHandler,而后将接收到的消息作过滤,知足条件回写消息事件

  
    
  
  
   
   
            
   
   
private static class OrderServerHandler extends ChannelHandlerAdapter {    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        OrderRequest request = (OrderRequest) msg;        if ("Levin".equalsIgnoreCase(request.getUserName())) {//若是是Levin购买的,返回消息            System.out.println("Service Accept Client Order Request :[" + request.toString() + "]");            ctx.writeAndFlush(response(request.getOrderId()));        }    }    private OrderResponse response(Integer orderId) {        OrderResponse response = new OrderResponse();        response.setOrderId(orderId);        response.setRespCode("200");        response.setDesc("下单成功");        return response;    }}

OrderClient

1.建立 OrderClientHandler,请求 3次而后将数据写入缓冲区后调用 flush发送

  
    
  
  
   
   
            
   
   
private static class OrderClientHandler extends ChannelHandlerAdapter {    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        for (int i = 1; i <= 3; i++) {            ctx.write(request(i));        }        ctx.flush();    }    private Object request(int i) {        OrderRequest request = new OrderRequest();        request.setAddress("上海市青浦区赵重公路1888号");        request.setOrderId(i);        request.setPhoneNumber("130XXXX1912");        request.setProductName("一块儿来学Netty");        request.setUserName("Levin");        return request;    }    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        System.out.println("Receive Server Response :[" + msg + "]");    }}

试验一把

分别启动 OrderServer和 OrderClient,将会看到以下日志

  
    
  
  
   
   
            
   
   
绑定端口,同步等待成功......Service Accept Client Order Request :[OrderRequest{orderId=1, userName='Levin', productName='一块儿来学Netty', phoneNumber='130XXXX1912', address='上海市青浦区赵重公路1888号'}]Service Accept Client Order Request :[OrderRequest{orderId=2, userName='Levin', productName='一块儿来学Netty', phoneNumber='130XXXX1912', address='上海市青浦区赵重公路1888号'}]Service Accept Client Order Request :[OrderRequest{orderId=3, userName='Levin', productName='一块儿来学Netty', phoneNumber='130XXXX1912', address='上海市青浦区赵重公路1888号'}]---------------------------------------------------------------------------------------------------------Receive Server Response :[OrderResponse{orderId=1, respCode='200', desc='下单成功'}]Receive Server Response :[OrderResponse{orderId=2, respCode='200', desc='下单成功'}]Receive Server Response :[OrderResponse{orderId=3, respCode='200', desc='下单成功'}]

总结

本章介绍了如何利用 Netty提供的解码器与编码器实现对普通的对象进行序列化操做,经过订单案例能够发现 Netty为咱们作了不少事情,短短几行代码就能完成序列化操做,咱们只需关注自身业务便可,极大的提升了开发效率....

- 说点什么

微信公众号: battcn(欢迎调戏)

全文代码:https://git.oschina.net/battcn/battcn-netty/tree/master/Chapter6-1/battcn-netty-6-1-1

  • 我的QQ:1837307557

  • battcn开源群(适合新手):391619659


本文分享自微信公众号 - battcn(battcn)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索