.
131 | *
132 | * 如果JSON字符串为Null或"null"字符串, 返回Null. 如果JSON字符串为"[]", 返回空集合.
133 | *
134 | * 如需反序列化复杂Collection如List, 请使用fromJson(String,JavaType)
135 | *
136 | * @see #fromJson(String, JavaType)
137 | */
138 | @JsonCreator
139 | public static T fromJson(String jsonString, Class clazz) {
140 | try {
141 | return mapper.readValue(jsonString, clazz);
142 | } catch (Exception e) {
143 | log.error(jsonString, e);
144 | }
145 | return null;
146 | }
147 |
148 | /**
149 | * 反序列化复杂Collection如List, 先使用函数createCollectionType构造类型,然后调用本函数.
150 | *
151 | * @see #createCollectionType(Class, Class...)
152 | */
153 | public static T fromJson(String jsonString, JavaType javaType) {
154 | try {
155 | return mapper.readValue(jsonString, javaType);
156 | } catch (Exception e) {
157 | log.error(jsonString, e);
158 | }
159 | return null;
160 | }
161 |
162 | public static NettyMessage fromJson(byte[] array, Class nettyMessageClass) {
163 | try {
164 | return mapper.readValue(array, NettyMessage.class);
165 | } catch (IOException e) {
166 | e.printStackTrace();
167 | log.error(e.getMessage(), e);
168 | }
169 | return null;
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/src/main/java/com/lanux/io/netty/NettyClient.java:
--------------------------------------------------------------------------------
1 | package com.lanux.io.netty;
2 |
3 | import com.lanux.io.NetConfig;
4 | import io.netty.bootstrap.Bootstrap;
5 | import io.netty.buffer.PooledByteBufAllocator;
6 | import io.netty.channel.*;
7 | import io.netty.channel.nio.NioEventLoopGroup;
8 | import io.netty.channel.socket.SocketChannel;
9 | import io.netty.channel.socket.nio.NioSocketChannel;
10 | import io.netty.handler.timeout.IdleStateHandler;
11 | import org.apache.commons.lang3.RandomStringUtils;
12 | import org.apache.commons.lang3.RandomUtils;
13 | import org.apache.commons.lang3.StringUtils;
14 |
15 | import java.util.concurrent.ThreadFactory;
16 | import java.util.concurrent.TimeUnit;
17 | import java.util.concurrent.atomic.AtomicInteger;
18 |
19 | /**
20 | * Created by lanux on 2017/9/16.
21 | */
22 | public class NettyClient {
23 | //nThreads=0: Netty 会首先从系统属性中获取 "io.netty.eventLoopThreads" 的值, 如果我们没有设置它的话, 那么就返回默认值: 处理器核心数 * 2.
24 | EventLoopGroup workerGroup = new NioEventLoopGroup(0,
25 | new ThreadFactory() {
26 | AtomicInteger count = new AtomicInteger(1);
27 |
28 | @Override
29 | public Thread newThread(Runnable r) {
30 | return new Thread(r, "NioEventLoop-" + count.getAndIncrement());
31 | }
32 | });
33 |
34 | final Bootstrap b = new Bootstrap();
35 |
36 | public NettyClient() throws Exception {
37 | b.group(workerGroup)
38 | .channel(NioSocketChannel.class)
39 | .option(ChannelOption.SO_KEEPALIVE, true)
40 | .option(ChannelOption.TCP_NODELAY, true)
41 | .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
42 | .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, NetConfig.SO_TIMEOUT)
43 | //Each channel has its own pipeline and it is created automatically when a new channel is created.
44 | .handler(new ChildChannelHandler());
45 | }
46 |
47 | public static class ChildChannelHandler extends
48 | ChannelInitializer {
49 |
50 | @Override
51 | protected void initChannel(SocketChannel ch) throws Exception {
52 | ch.pipeline().addLast(new IdleStateHandler(0, 0, 30, TimeUnit.SECONDS))
53 | .addLast(new NettyMessageDecoder())
54 | .addLast(new NettyMessageEncoder())
55 | .addLast(new NettyMessageHandler());
56 | }
57 |
58 | }
59 |
60 | public Channel connect(String host, int port) {
61 | Channel channel;
62 | ChannelFuture connectFuture = b.connect(host, port);
63 | System.out.println("Netty time Client connected at port " + port);
64 | try {
65 | channel = connectFuture.sync().channel();
66 | } catch (Exception e) {
67 | // TODO 需要进一步验证这种机制,是否可以确保关闭连接。
68 | connectFuture.cancel(true);
69 | channel = connectFuture.channel();
70 | if (channel != null) {
71 | channel.close();
72 | }
73 | System.out.println("connect server fail " + host + ":" + port);
74 | e.printStackTrace();
75 | }
76 | return channel;
77 | }
78 |
79 | public static void main(String[] args) {
80 | try {
81 | Channel connect = new NettyClient().connect(NetConfig.SERVER_IP, NetConfig.SERVER_PORT);
82 | NettyMessage msg = new NettyMessage();
83 | msg.setHeader(new Header());
84 | for (int i = 0; i < 100; i++) {
85 | msg.getHeader().setSessionID(1000001+i);
86 | msg.setBody(i + "=" + RandomStringUtils.randomAlphabetic(RandomUtils.nextInt(1000, 20000)));
87 | connect.writeAndFlush(msg);
88 | TimeUnit.SECONDS.sleep(1);
89 | }
90 | } catch (Exception e) {
91 | e.printStackTrace();
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/com/lanux/io/netty/NettyMessage.java:
--------------------------------------------------------------------------------
1 | package com.lanux.io.netty;
2 |
3 | /**
4 | * Created by lanux on 2017/9/16.
5 | */
6 | public class NettyMessage {
7 | private Header header;
8 | private Object body;
9 | public Header getHeader() {
10 | return header;
11 | }
12 | public void setHeader(Header header) {
13 | this.header = header;
14 | }
15 | public Object getBody() {
16 | return body;
17 | }
18 | public void setBody(Object body) {
19 | this.body = body;
20 | }
21 |
22 | public String toString(){
23 | return "NettyMessage [header=" + header + "]";
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/lanux/io/netty/NettyMessageDecoder.java:
--------------------------------------------------------------------------------
1 | package com.lanux.io.netty;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.handler.codec.ByteToMessageDecoder;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * https://github.com/linweiliang451791119/NIO/blob/master/nio/src/chapter13/NettyMarshallingEncoder.java
11 | * Created by lanux on 2017/9/16.
12 | */
13 | public class NettyMessageDecoder extends ByteToMessageDecoder {
14 |
15 | public NettyMessageDecoder() {
16 | super();
17 | }
18 |
19 | @Override
20 | protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List