JBoss Marshalling 是一个java 对象序列化包,对JDK 默认的序列华框架进行了优化,但又保持跟java.io.Serizlizable 接口的兼容,同时增加了一些可调的参数和附加的特性,这些参数和特性可通过工厂进行配置。
Netty-JBoss实例:
1 maven pom.xml 导入
<dependency>
<groupId>org.jboss.marshalling</groupId>
<artifactId>jboss-marshalling-serial</artifactId>
<version>1.4.11.Final</version>
</dependency>
2 创建Jboss Marshalling解码器MarshallingDecoder
import io.netty.handler.codec.marshalling.*;
import org.jboss.marshalling.*;
public class MarshallingCodeCFactory {
/**
* 创建Jboss Marshalling解码器MarshallingDecoder
*
* @return MarshallingDecoder
*/
public static MarshallingDecoder buildMarshallingDecoder()
{
// 参数serial标识创建的是java序列化工厂对象。
final MarshallerFactory marshallerFactory = Marshalling
.getProvidedMarshallerFactory("serial");
// 创建了MarshallingConfiguration对象,配置了版本号为5
final MarshallingConfiguration configuration = new MarshallingConfiguration();
configuration.setVersion(5);
// 根据marshallerFactory和configuration创建provider
UnmarshallerProvider provider = new DefaultUnmarshallerProvider(
marshallerFactory , configuration);
// 构建Netty的MarshallingDecoder对象,俩个参数分别为provider和单个消息序列化后的最大长度
return new MarshallingDecoder(provider ,
1024 * 1024 * 1);
}
/**
* 创建Jboss Marshalling编码器MarshallingEncoder
*
* @return MarshallingEncoder
*/
public static MarshallingEncoder buildMarshallingEncoder()
{
final MarshallerFactory marshallerFactory = Marshalling
.getProvidedMarshallerFactory("serial");
final MarshallingConfiguration configuration = new MarshallingConfiguration();
configuration.setVersion(5);
MarshallerProvider provider = new DefaultMarshallerProvider(
marshallerFactory , configuration);
// 构建Netty的MarshallingEncoder对象,MarshallingEncoder用于实现序列化接口的POJO对象序列化为二进制数组
return new MarshallingEncoder(provider);
}
}
3 Netty 的 Marshalling 服务端方法
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import java.net.InetSocketAddress;
public class Server {
public void bind(int port) throws InterruptedException
{
EventLoopGroup boss=new NioEventLoopGroup();
EventLoopGroup worker=new NioEventLoopGroup();
try
{
ServerBootstrap b=new ServerBootstrap();
b.group(boss,worker)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1280)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>()
{
@Override
protected void initChannel(SocketChannel ch) throws Exception
{
// ch.pipeline().addLast(new ChannelHandler[]{MarshallingCodeCFactory.buildMarshallingEncoder()});
// ch.pipeline().addLast(new ChannelHandler[]{MarshallingCodeCFactory.buildMarshallingDecoder()});
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
ch.pipeline().addLast(
new ServerHandler()
);
}
});
ChannelFuture f=b.bind(port).sync();
f.channel().closeFuture().sync();
} finally
{
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException
{
int port = 8006;
new Server().bind(port);
}
}
4 Netty 的 Marshalling 服务端方法ServerHandler实现
import com.fasterxml.jackson.core.io.CharTypes;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ServerHandler extends ChannelInboundHandlerAdapter
{
@Override
public void channelRead(ChannelHandlerContext ctx , Object msg) throws Exception
{
UserInfo user= (UserInfo) msg;
System.out.println("收到:"+user);
ctx.writeAndFlush(reply(user));
}
private static GirlResponse reply(UserInfo user){
GirlResponse gr=new GirlResponse();
gr.setMsg("to "+user.getName()+" : 测试");
return gr;
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx , Throwable cause) throws Exception
{
cause.printStackTrace();
ctx.close();
}
}
5 Netty 的 Marshalling 客户端
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
public class Client {
public void connect(int port, String host) throws InterruptedException
{
EventLoopGroup group = new NioEventLoopGroup();
try
{
Bootstrap b=new Bootstrap();
b.group(group)
.option(ChannelOption.TCP_NODELAY, true)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>()
{
@Override
protected void initChannel(SocketChannel ch) throws Exception
{
// ch.pipeline().addLast(new ChannelHandler[]{MarshallingCodeCFactory.buildMarshallingEncoder()});
// ch.pipeline().addLast(new ChannelHandler[]{MarshallingCodeCFactory.buildMarshallingDecoder()});
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
ch.pipeline().addLast(new ClientHandler());
}
});
ChannelFuture f= b.connect(host, port).sync();
f.channel().closeFuture().sync();
} finally
{
group.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException
{
int port = 8006;
String host="127.0.0.1";
new Client().connect(port, host);
}
}
6 Netty 的 Marshalling 客户端ClientHandler 方法实现
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.util.Random;
public class ClientHandler extends ChannelInboundHandlerAdapter {
public void channelActive(ChannelHandlerContext ctx) throws Exception
{
System.out.println("同学测试:");
Random r = new Random();
for (int i = 1; i <= 5; i++)
{
UserInfo user = new UserInfo();
user.setName("同学 " + i);
user.setHeight(r.nextInt(25) + 160);
ctx.write(user);
System.out.println(user);
}
ctx.flush();
}
public void channelRead(ChannelHandlerContext ctx , Object msg) throws Exception
{
GirlResponse gr= (GirlResponse) msg;
System.out.println("收到测试回复 :"+gr.getMsg());
}
public void exceptionCaught(ChannelHandlerContext ctx , Throwable cause) throws Exception
{
cause.printStackTrace();
ctx.close();
}
}
7运行结果: