Netty之HTTP+XML编解码框架开发

Netty之HTTP+XML编解码框架开发

一.HTTP+XML请求消息编码类

    对于上层业务,构造订购请求消息后,以HTTP+XML协议将消息发送给服务端,如果要实现对业务零侵入或者尽可能少的侵入看,协议层和应用层应该解耦。

    考虑到HTTP+XML协议栈需要一定的定制扩展能力,例如通过HTTP消息头携带业务自定义字段,应该允许业务利用Netty的HTTP协议栈接口自行构造私有的HTTP消息头。

    HTTP+XML的协议编码仍然采用ChannelPipeline中增加对应的编码handler类实现。

1.1 HttpXmlRequestEncode实现

  packagejibx;

 

import java.net.InetAddress;

import java.util.List;

 

importio.netty.channel.ChannelHandlerContext;

importio.netty.handler.codec.http.DefaultFullHttpRequest;

importio.netty.handler.codec.http.FullHttpRequest;

importio.netty.handler.codec.http.HttpHeaders;

/*

 *HTTP+XML HTTP请求消息编码类

 *

 */

public class HttpXmlRequestEncoder

     extends AbstarctHttpXmlEncoder<HttpXmlRequest>{

        

   @Override

   protected void encode(ChannelHandlerContext ctx,HttpXmlRequestmsg,List<Object> out)

   throws Exception{

             // 调用父类的encode0,将业务需要发送的POJO对象Order实例通过jibx序列化为XML字符串

             // 随后将它封装成netty的bytebuf

             ByteBufbody=encode0(ctx,msg.getBody());

             FullHttpRequestrequest=msg.getRequest();

             // 对消息头进行判断,如果业务侧自定义和定制了消息头,则使用业务侧设置的HTTP消息头

             // 如果业务侧没有设置,则构造新的HTTP消息头

             if(request==null){

                       // 构造和设置默认的HTTP消息头,由于通常情况下HTTP通信双方更关注消息体本身,

                       // 所以这里采用了硬编码方式,如果要产品化,可以做成XML配置文件,允许业务自定义配置,

                       // 以提升定制的灵活性

                       request=newDefaultFullHttpRequest(HttpVersion.HTTP_1_1,HttpMethod.GET,"/do",body);

                       HttpHeadersheaders=request.headers();

                       headers.set(HttpHeaders.Names.HOST,InetAddress.getLocalHost().getHostAddress());

                       headers.set(HttpHeaders.Names.CONNECTION,HttpHeaders.Value.CLOSE);

                       headers.set(HttpHeaders.Names.ACCEPT_ENCODING,HttpHeaders.Value.GZIP.toString()+','+

                                         HttpHeaders.Value.DEFLATE.toString());

                       headers.set(HttpHeaders.Names.ACCEPT_CHARSET,"ISO-8859,utf-8,q=0.7,*;q=0.7");

                       headers.set(HttpHeaders.Names.USER_AGENT,"Nettyxml Http Client side");

                       headers.set(HttpHeaders.Names.ACCEPT,"text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8");

             }

             // 由于请求消息消息体不为空,也没有chunk方式,所以在HTTP消息头中设置消息体的长度conent-length

             // 完成消息体的XML序列化后将重新构造的HTTP请求消息加入到out中

             // 由后续netty的http请求编码器继续对HTTP请求消息进行编码

             HttpHeaders.setContentLength(request,body.eradableBytes());

             out.add(request);

}

}

1.2 AbstrctHttpXmlEncoder实现

package jibx;

 

import java.io.StringWriter;

import io.netty.buffer.ByteBuf;

import io.netty.buffer.Unpooled;

importio.netty.channel.ChannelHandlerContext;

importio.netty.handler.codec.MessageToMessageEncoder;

/*

 *HTTP+XML HTTP请求消息编码基类

 */

public classAbstractHttpXmlEncoder<T>

 extends MessageToMessageEncoder<T>{

         IBindingFactoryfactory=null;

         StringWriterwriter=null;

         finalstatic String CHARSET_NAME="UTF-8";

         finalstatic Charset UTF-8=

                            Charset.forName(CHARSET_NAME);

         //将业务的Order实例序列化为XML字符串

         protectedByteBuf encode0(ChannelHandlerContext ctx,Object body) throws Exception{

                   factory=BindingDirectory.getFactory(body.getClass());

                   writer=newStringWriter();

                   IMarshallingContextmctx=factory.createMarshallingContext();

                   mctx.setIndent(2);

                   mctx.marshalDocument(body,CHARSET_NAME,null,writer);

                   StringxmlStr=writer.toString();

                   writer.close();

                   writer=null;

                   //将XML字符串包装成netty的ByteBuf并返回,实现了HTTP请求消息的XML编码

                   ByteBufencodeBuf=Unpooled.copiedBuffer(xmlStr,UTF-8);

                   returnencodeBuf;

         }

        

         @Override

         publicvoid exceptionCaught(ChannelHandlerContext ctx,Throwable cause) throwsException{

                   //释放资源

                   if(writer!=null){

                            writer.close();

                            writer=null;

                           

                   }

         }

}

1.3 HttpXmlRequest实现

package jibx;

/*

 *HTTP+XML请求消息  用于实现和协议栈之间的解耦

 */

importio.netty.handler.codec.http.FullHttpRequest;

 

public class HttpXmlRequest {

         privateFullHttpRequest request;

         privateObject body;

        

         publicHttpXmlRequest(FullHttpRequest request,Object body){

                   this.request=request;

                   this.body=body;

                  

         }

        

         publicfinal FullHttpRequest getRequest(){

                   returnrequest;

         }

        

         publicfinal void setRequest(FullHttpRequest request){

                   this.request=request;

         }

        

         publicfinal Object getBody(){

                   returnbody;

         }

        

         publicfinal void setBody(Object body){

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值