zoukankan      html  css  js  c++  java
  • CXF 拦截器 拦截请求和发送时的报文

    参考:https://blog.csdn.net/yczz/article/details/16809859#commentBox

    http://cxf.apache.org/docs/interceptors.html

    https://elim.iteye.com/blog/2248620#_Toc431737707

    cxf 可以对请求和发送时的报文进行拦截,然后对其进行加工成我们想要的格式,然后再放到回去!!!!!

    我实现的是自定义拦截器

    1.在需要拦截的方法上面加上这个注解,注解里面是我们的自定义拦截器

    @OutInterceptors(interceptors = { "com.deloitte.tms.vat.webservice.result1.CDATAOutInterceptor" })
    @InInterceptors(interceptors="com.deloitte.tms.vat.webservice.result1.ArtifactOutInterceptor")

    2.对返回时的格式进行拦截实例,如果

    public CDATAOutInterceptor() {
         //这里代表流关闭之前的阶段,这很重要!可以到官网去看,拦截的阶段分为很多种 super(Phase.PRE_STREAM); }
    Phase.PRE_STREAM写的阶段不对可能会对想要的结果有影响,我开始写的Send和Write都是不生效的,网上也有好多博文写的是这种!!!踩到坑了!
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import org.apache.cxf.helpers.IOUtils;
    import org.apache.cxf.io.CachedOutputStream;
    import org.apache.cxf.message.Message;
    import org.apache.cxf.phase.AbstractPhaseInterceptor;
    import org.apache.cxf.phase.Phase;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class CDATAOutInterceptor extends AbstractPhaseInterceptor<Message> {
        private static final Logger log = LogManager.getLogger(ArtifactOutInterceptor.class);
    
        public CDATAOutInterceptor() {
         //这里代表流关闭之前的阶段,这很重要!可以到官网去看,拦截的阶段分为很多种
    super(Phase.PRE_STREAM); } @Override public void handleMessage(Message message) { /*这里是通过注解的方式来加<!CDATA[[]]>的格式 * message.put("disable.outputstream.optimization", Boolean.TRUE); * XMLStreamWriter writer = * StaxUtils.createXMLStreamWriter(message.getContent(OutputStream.class * )); message.setContent(XMLStreamWriter.class, new * CDATAXMLStreamWriter(writer)); */       try { OutputStream os = message.getContent(OutputStream.class); CachedStream cs = new CachedStream(); message.setContent(OutputStream.class, cs); message.getInterceptorChain().doIntercept(message); CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class); InputStream in = csnew.getInputStream(); String xml = IOUtils.toString(in); System.out.println("replaceBegin" + xml);        //转换的方式 xml = xml.replace("<body>", "<![CDATA[<?xml version="1.0" encoding="UTF-8"?><body>") .replace("<returnMessage>", "<returnMessage><![CDATA[") .replace("</returnMessage>", "]]></returnMessage>").replace("<returnCode>", "<returnCode><![CDATA[") .replace("</returnCode>", "]]></returnCode>"); // 这里对xml做处理,处理完后同理,写回流中 System.out.println("replaceAfter" + xml); IOUtils.copy(new ByteArrayInputStream(xml.getBytes()), os); cs.close(); os.flush(); message.setContent(OutputStream.class, os); } catch (Exception e) { log.error("Error when split original inputStream. CausedBy : " + " " + e); } } private class CachedStream extends CachedOutputStream { public CachedStream() { super(); } protected void doFlush() throws IOException { currentStream.flush(); } protected void doClose() throws IOException { } protected void onWrite() throws IOException { } } }

    如果上请求的数据量过大的话:会出现传输的xml获取不到数据的情况。需要将CachedStream换成ByteArrayOutputStream,

    如下的方式:

     1 @Override
     2     public void handleMessage(Message message) {
     3         try {
     4 
     5             OutputStream os = message.getContent(OutputStream.class);
     6             ByteArrayOutputStream cs=new ByteArrayOutputStream();
     7 
     8             message.setContent(OutputStream.class, cs);
     9 
    10             message.getInterceptorChain().doIntercept(message);
    11 
    12             //ByteArrayOutputStream csnew = (ByteArrayOutputStream) message.getContent(ByteArrayOutputStream.class);
    13             //InputStream in = csnew.toString(charsetName);
    14             //String xml = IOUtils.toString(in);
    15             String xml=new String(cs.toByteArray(), "utf-8");
    16             log.info("replaceBegin"+xml);
    17             xml = xml.replace(""0;
    18             // 这里对xml做处理,处理完后同理,写回流中
    19             log.info("replaceAfter"+xml);
    20             IOUtils.copy(new ByteArrayInputStream(xml.getBytes()), os);
    21             cs.close();
    22             os.flush();
    23             log.info("将参数设置会cxf框架中------------");
    24             message.setContent(OutputStream.class, os);
    25 
    26         } catch (Exception e) {
    27             log.error("Error when split original inputStream. CausedBy : " + "
    " + e);
    28         }
    29     }

    3.对请求进行拦截

    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import org.apache.cxf.binding.soap.SoapMessage;
    import org.apache.cxf.helpers.IOUtils;
    import org.apache.cxf.phase.AbstractPhaseInterceptor;
    import org.apache.cxf.phase.Phase;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    public class ArtifactOutInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
        private static final Logger log = LogManager.getLogger(ArtifactOutInterceptor.class); 
         
        public ArtifactOutInterceptor() { 
            //这儿使用pre_stream,意思为在流关闭之前 
            super(Phase.PRE_STREAM); 
        } 
        @Override
        public void handleMessage(SoapMessage message) {
            InputStream is = message.getContent(InputStream.class);
            if (is != null) {
                try {
                    String str = IOUtils.toString(is);
                    log.info("原格式--传入的xml格式为:"+str);
                    str=str.replace("&lt;", "<");
                    str=str.replace("&gt;", ">");
                    str=str.replace("<?xml version="1.0" encoding="UTF-8"?>","");
                    InputStream ism = new ByteArrayInputStream(str.getBytes());
                    message.setContent(InputStream.class, ism);
                    log.info("解析后的格式--传入的xml格式为:"+str);
                }
                catch(IOException e){
                    log.error("WebService消息拦截器处理异常!",e);
                }
            }
    
        } 
    }

    4.1.对输出加<CADATA[[]]>的另外一种方法

    
    

    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;

    
    

    import javax.xml.stream.XMLStreamWriter;

    
    

    import org.apache.cxf.helpers.IOUtils;
    import org.apache.cxf.io.CachedOutputStream;
    import org.apache.cxf.message.Message;
    import org.apache.cxf.phase.AbstractPhaseInterceptor;
    import org.apache.cxf.phase.Phase;
    import org.apache.cxf.staxutils.StaxUtils;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;

    
    

    public class CDATAOutInterceptor extends AbstractPhaseInterceptor<Message> {
      private static final Logger log = LogManager.getLogger(ArtifactOutInterceptor.class);

    
    

      public CDATAOutInterceptor() {
        super(Phase.PRE_STREAM);
      }

    
    

      @Override
      public void handleMessage(Message message) {

        message.put("disable.outputstream.optimization", Boolean.TRUE);
        XMLStreamWriter writer =
        StaxUtils.createXMLStreamWriter(message.getContent(OutputStream.class
        )); message.setContent(XMLStreamWriter.class, new
        CDATAXMLStreamWriter(writer));

      }

    }

    import java.util.Arrays;
    
    import javax.xml.stream.XMLStreamException;
    import javax.xml.stream.XMLStreamWriter;
    
    import org.apache.cxf.staxutils.DelegatingXMLStreamWriter;
    
    public class CDATAXMLStreamWriter extends DelegatingXMLStreamWriter{
        private String currentElementName;
        private static String[] CDATA_ELEMENTS = { "returnCode", "returnMessage",
                "fpdm", "fphm","code", 
                "smrq","kpfsh","kprq","fpje","fpse", "sl","spfsh", "spfmc","fply","fplx", "xgrq","zfbz" 
                , "rzrq","rzzt","body","start_time","end_time"};
        public CDATAXMLStreamWriter(XMLStreamWriter writer) {
            super(writer);
        }
    
        @Override
        public void writeCharacters(String text) throws XMLStreamException {
            boolean useCData = isNeedCData();
            if (useCData) {
                super.writeCData(text);
            } else {
                super.writeCharacters(text);
            }
        }
    
        private boolean isNeedCData() {
            if(currentElementName.equals("body")||currentElementName.equals("data")){
                System.out.println("-------");
            }
            if (Arrays.asList(CDATA_ELEMENTS).contains(currentElementName)) {
                return true;
            } else {
                return false;
            }
            
        }
    
        public void writeStartElement(String prefix, String local, String uri)
                throws XMLStreamException {
            currentElementName = local;
            super.writeStartElement(prefix, local, uri);
        }
    }
  • 相关阅读:
    TapTap推广统计逻辑
    广告推广测试
    背压(Backpressure)机制
    工作相关资料
    ElasticSearch问题记录
    bfrd collector性能排查
    Ubuntu13.10下安装HADOOP
    Hadoop各商业发行版之比较
    Behave用户自定义数据类型
    Behave step matcher
  • 原文地址:https://www.cnblogs.com/fengxiaoyuan/p/10683806.html
Copyright © 2011-2022 走看看