在做JAVA
开发的时候,接触最多的就是java.io.Serializable
,通过该接口生成序列化ID,然后就可以通过java.io.ObjectInput
与java.io.ObjectOutput
进行序列化与反序列化,无需考虑跨语言调用,对序列化性能要求不高的情况,使用默认的是最方便的,虽然存在弊端,但也能满足大部分的需要….
为了更好的掌握Netty
序列化相关知识,本章使用Netty
给我们提供的ObjectEncoder
与ObjectDecoder
对订单请求与应答消息进行序列化操作…
开发例程
- 在服务端
ChannelPipeline
新增解码器io.netty.handler.codec.serialization.ObjectDecoder
- 在服务端
ChannelPipeline
新增解码器io.netty.handler.codec.serialization.ObjectEncoder
- 实体类实现
java.io.Serializable
序列化接口
1.创建OrderRequest
与 OrderResponse
两个Java
类
1 2 3 4 5 6 7 8 9 10
| 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; }
|
1 2 3 4 5 6 7 8
| 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
编码器
1 2 3 4 5 6
| @Override protected 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(int maxObjectSize, ClassResolver classResolver)
,第一个参数是设置序列化对象的最大字节长度,如果超出限定范围会抛出StreamCorruptedException
,默认(1024 * 1024 = 1048576字节),第二个参数用于做类解码
操作
2.创建OrderServerHandler
,然后将接收到的消息做过滤,满足条件回写消息事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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())) { 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
发送
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 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
,将会看到如下日志
1 2 3 4 5 6 7 8 9
| 绑定端口,同步等待成功...... 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
为我们做了很多事情,短短几行代码就能完成序列化操作,我们只需关注自身业务即可,极大的提高了开发效率….
- 说点什么
全文代码:https://git.oschina.net/battcn/battcn-netty/tree/master/Chapter6-1/battcn-netty-6-1-1
- 个人QQ:1837307557
- battcn开源群(适合新手):391619659
微信公众号:battcn
(欢迎调戏)