Marshalling在netty中的基本使用(Hello World)

来源:互联网 发布:视频分析软件 编辑:程序博客网 时间:2024/06/06 07:40

    • Client 客户端
    • ClientHandler 客户端处理类
    • MarshallingCodeCFactory 编解码工厂类
    • Request 请求数据对象
    • Response 响应数据对象
    • Server 服务端
    • ServerHandler 服务端处理类

JBoss Marshalling的官网: http://jbossmarshalling.jboss.org/downloads

Marshalling是一个java对象的序列化API包,修正了java自带的序列化包的很多问题,但又保持跟java.io.Serializable接口的兼容,同时又增加了一些可调的参数和附加特性,并且这些参数和特性可通过工厂类的配置。

参考我的另一文章: 目前java序列化流行的编解码框架

简单的介绍 JBoss 的 Marshalling (1.3.0) 在netty (5.0) 中的使用,属于Hello World,看代码就基本会用了。

Client 客户端

package bhz.netty.marshalling;import io.netty.bootstrap.Bootstrap;import io.netty.channel.*;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioSocketChannel;public class Client {    public void connect(int port, String host) throws Exception {        // 配置客户端NIO线程组        EventLoopGroup group = new NioEventLoopGroup();        try {            Bootstrap bootstrap = new Bootstrap();            bootstrap.group(group)//                    .channel(NioSocketChannel.class)//                    .option(ChannelOption.TCP_NODELAY, true)//                    .handler(new ChannelInitializer() {//                        public void initChannel(Channel ch) throws Exception {                            // Marshalling 解码器                            ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());                            // Marshalling 编码器                            ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());                            ch.pipeline().addLast(new ClientHandler());                        }                    });            // 发起异步连接操作            ChannelFuture f = bootstrap.connect(host, port).sync();            // 等待客户端链路关闭            f.channel().closeFuture().sync();        } finally {            // 优雅退出,释放NIO线程组            group.shutdownGracefully();        }    }    public static void main(String[] args) throws Exception {        int port = 8080;        if (args != null && args.length > 0) {            try {                port = Integer.valueOf(args[0]);            } catch (NumberFormatException e) {                // 采用默认值            }        }        new Client().connect(port, "127.0.0.1");    }}

ClientHandler 客户端处理类

package bhz.netty.marshalling;import io.netty.channel.ChannelHandlerAdapter;import io.netty.channel.ChannelHandlerContext;public class ClientHandler extends ChannelHandlerAdapter {    public ClientHandler() {    }    @Override    public void channelActive(ChannelHandlerContext ctx) {        //在链路激活的时候循环构造10条订购请求消息,最后一次性地发送给服务端。        for (int i = 0; i < 10; i++) {            ctx.write(subReq(i));        }        ctx.flush();    }    private Request subReq(int i) {        Request req = new Request();        req.setAddress("北京市朝阳区望京SOHO..");        req.setPhoneNumber("188xxxxxxxxx");        req.setProductName("Netty For Marshalling");        req.setSubReqID(i);        req.setUserName("zhangsan");        return req;    }    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        //由于对象解码器已经对订购请求应答消息进行了自动解码,        //因此,ClientHandler接收到的消息已经是解码成功后的订购应答消息。        System.out.println("Receive server response : [" + msg + "]");    }    @Override    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {        ctx.flush();    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {        cause.printStackTrace();        ctx.close();    }}

MarshallingCodeCFactory 编解码工厂类

package bhz.netty.marshalling;import io.netty.handler.codec.marshalling.*;import org.jboss.marshalling.MarshallerFactory;import org.jboss.marshalling.Marshalling;import org.jboss.marshalling.MarshallingConfiguration;/** * Marshalling 编码和解码的工厂类 * */public final class MarshallingCodeCFactory {    /**     * 创建Jboss Marshalling解码器MarshallingDecoder     */    public static MarshallingDecoder buildMarshallingDecoder() {        //首先通过Marshalling工具类的getProvidedMarshallerFactory静态方法获取MarshallerFactory实例        //参数“serial”表示创建的是Java序列化工厂对象,它由jboss-marshalling-serial-1.3.0.CR9.jar提供。        final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");        //创建了MarshallingConfiguration对象        final MarshallingConfiguration configuration = new MarshallingConfiguration();        //将它的版本号设置为5        configuration.setVersion(5);        //然后根据MarshallerFactory和MarshallingConfiguration创建UnmarshallerProvider实例        UnmarshallerProvider provider = new DefaultUnmarshallerProvider(marshallerFactory, configuration);        //最后通过构造函数创建Netty的MarshallingDecoder对象        //它有两个参数,分别是UnmarshallerProvider和单个消息序列化后的最大长度。        MarshallingDecoder decoder = new MarshallingDecoder(provider, 1024);        return decoder;    }    /**     * 创建Jboss Marshalling编码器MarshallingEncoder     */    public static MarshallingEncoder buildMarshallingEncoder() {        final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");        final MarshallingConfiguration configuration = new MarshallingConfiguration();        configuration.setVersion(5);        //创建MarshallerProvider对象,它用于创建Netty提供的MarshallingEncoder实例        MarshallerProvider provider = new DefaultMarshallerProvider(marshallerFactory, configuration);        //MarshallingEncoder用于将实现序列化接口的POJO对象序列化为二进制数组。        MarshallingEncoder encoder = new MarshallingEncoder(provider);        return encoder;    }}

Request 请求数据对象

package bhz.netty.marshalling;import java.io.Serializable;public class Request 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 "Request [subReqID=" + subReqID + ", userName=" + userName + ", productName=" + productName + ", phoneNumber=" + phoneNumber + ", address=" + address + "]";    }}

Response 响应数据对象

package bhz.netty.marshalling;import java.io.Serializable;public class Response implements Serializable {    private static final long serialVersionUID = 1L;    private int subReqID;    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 "Response [subReqID=" + subReqID + ", respCode=" + respCode + ", desc=" + desc + "]";    }}

Server 服务端

package bhz.netty.marshalling;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.*;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;import io.netty.handler.logging.LogLevel;import io.netty.handler.logging.LoggingHandler;public class Server {    public void bind(int port) throws Exception {        // 配置服务端的NIO线程组        EventLoopGroup bossGroup = new NioEventLoopGroup();        EventLoopGroup workerGroup = new NioEventLoopGroup();        try {            ServerBootstrap serverBootstrap = new ServerBootstrap();            serverBootstrap.group(bossGroup, workerGroup)//                    .channel(NioServerSocketChannel.class)//                    .option(ChannelOption.SO_BACKLOG, 100)//                    .handler(new LoggingHandler(LogLevel.INFO))//                    .childHandler(new ChannelInitializer() {//                        public void initChannel(Channel ch) {                            // 通过工厂类创建MarshallingEncoder解码器,并添加到ChannelPipeline.                            ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());                            // 通过工厂类创建MarshallingEncoder编码器,并添加到ChannelPipeline中。                            ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());                            ch.pipeline().addLast(new ServerHandler());                        }                    });            // 绑定端口,同步等待成功            ChannelFuture f = serverBootstrap.bind(port).sync();            // 等待服务端监听端口关闭            f.channel().closeFuture().sync();        } finally {            // 优雅退出,释放线程池资源            bossGroup.shutdownGracefully();            workerGroup.shutdownGracefully();        }    }    public static void main(String[] args) throws Exception {        int port = 8080;        if (args != null && args.length > 0) {            try {                port = Integer.valueOf(args[0]);            } catch (NumberFormatException e) {                // 采用默认值            }        }        new Server().bind(port);    }}

ServerHandler 服务端处理类

package bhz.netty.marshalling;import io.netty.channel.ChannelHandler;import io.netty.channel.ChannelHandlerAdapter;import io.netty.channel.ChannelHandlerContext;public class ServerHandler extends ChannelHandlerAdapter {    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {    }    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        // 经过解码器处理 ,接收到的请求消息(msg)已经被自动解码为Request对象,可以直接使用。        Request req = (Request) msg;        if ("zhangsan".equalsIgnoreCase(req.getUserName())) {            System.out.println("Service accept client : [" + req.toString() + "]");            // 对订购者的用户名进行合法性校验,校验通过后打印订购请求消息,构造订购成功应答消息立即发送给客户端。            ctx.writeAndFlush(resp(req.getSubReqID()));        }    }    private Response resp(int subReqID) {        Response resp = new Response();        resp.setSubReqID(subReqID);        resp.setRespCode(0);        resp.setDesc("Netty book order succeed, 3 days later, sent to the designated address");        return resp;    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {        cause.printStackTrace();        ctx.close();// 发生异常,关闭链路    }}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 香港海洋公园4日游 香港海洋公园一日游 全球无限战场 沐日海洋 湛江海洋大学是几本 大连海洋大学是几本 上海海洋大学是211吗 中国海洋大学是985吗 青岛海洋大学是211还是985 海洋芭莎是什么品牌 广东海洋大学是一本吗 厦门海洋学院是几本 大连海洋大学是一本吗 上海海洋大学是几本 浙江海洋大学是一本还是二本 中国海洋大学是211吗 你是我眼中的山川和海洋歌曲 中国海洋大学是几本 你是我眼中的山川和海洋txt 女的梦见海洋是什么预兆 知识是什么的海洋 广州海洋大学是几本 香港海洋公园门票价格是多少 海洋大学是几本 中国海洋大学是985还是211 香港海洋公园的门票是多少 广东海洋大学是一本还是二本 海洋主义是正规牌子吗 你是我眼中的山川和海洋免费 我国的海洋国土面积是多少 你是我眼中的山川与海洋 青岛海洋大学是几本 上海海洋大学是一本吗 浙江海洋学院是几本 你是我眼中的山川和海洋结局 你是我眼中的山川和海洋 广东海洋大学是211吗 上海海洋大学是基本 江苏海洋大学是一本吗 海洋公园门票是多少 北极熊是海洋动物吗 世界海洋日是几月几日