如何修改出站 CXF 请求的原始 XML 消息?

发布于 2024-11-27 16:20:42 字数 1136 浏览 4 评论 0原文

我想修改传出的 SOAP 请求。 我想从信封主体中删除 2 个 xml 节点。 我设法设置了一个拦截器,并将生成的消息集的字符串值获取到端点。

但是,以下代码似乎不起作用,因为传出消息未按预期进行编辑。有没有人有一些关于如何做到这一点的代码或想法?

public class MyOutInterceptor extends AbstractSoapInterceptor {

public MyOutInterceptor() {
        super(Phase.SEND); 
}

public void handleMessage(SoapMessage message) throws Fault { 
        // Get message content for dirty editing...
        StringWriter writer = new StringWriter();
        CachedOutputStream cos  = (CachedOutputStream)message.getContent(OutputStream.class); 
        InputStream inputStream = cos.getInputStream();
        IOUtils.copy(inputStream, writer, "UTF-8");
        String content = writer.toString();

        // remove the substrings from envelope...
        content = content.replace("<idJustification>0</idJustification>", "");
        content = content.replace("<indicRdv>false</indicRdv>", "");
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        outputStream.write(content.getBytes(Charset.forName("UTF-8")));
        message.setContent(OutputStream.class, outputStream);
} 

I would like to modify an outgoing SOAP Request.
I would like to remove 2 xml nodes from the Envelope's body.
I managed to set up an Interceptor and get the generated String value of the message set to the endpoint.

However, the following code does not seem to work as the outgoing message is not edited as expected. Does anyone have some code or ideas on how to do this?

public class MyOutInterceptor extends AbstractSoapInterceptor {

public MyOutInterceptor() {
        super(Phase.SEND); 
}

public void handleMessage(SoapMessage message) throws Fault { 
        // Get message content for dirty editing...
        StringWriter writer = new StringWriter();
        CachedOutputStream cos  = (CachedOutputStream)message.getContent(OutputStream.class); 
        InputStream inputStream = cos.getInputStream();
        IOUtils.copy(inputStream, writer, "UTF-8");
        String content = writer.toString();

        // remove the substrings from envelope...
        content = content.replace("<idJustification>0</idJustification>", "");
        content = content.replace("<indicRdv>false</indicRdv>", "");
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        outputStream.write(content.getBytes(Charset.forName("UTF-8")));
        message.setContent(OutputStream.class, outputStream);
} 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

勿忘初心 2024-12-04 16:20:42

根据第一条评论,我创建了一个抽象类,可以轻松地使用它来更改整个肥皂信封。

以防万一有人想要现成的代码部分。

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

import org.apache.commons.io.IOUtils;
import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor;
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.log4j.Logger;

/**
 * http://www.mastertheboss.com/jboss-web-services/apache-cxf-interceptors
 * http://stackoverflow.com/questions/6915428/how-to-modify-the-raw-xml-message-of-an-outbound-cxf-request
 * 
 */
public abstract class MessageChangeInterceptor extends AbstractPhaseInterceptor<Message> {

    public MessageChangeInterceptor() {
        super(Phase.PRE_STREAM);
        addBefore(SoapPreProtocolOutInterceptor.class.getName());
    }

    protected abstract Logger getLogger();

    protected abstract String changeOutboundMessage(String currentEnvelope);

    protected abstract String changeInboundMessage(String currentEnvelope);

    public void handleMessage(Message message) {
        boolean isOutbound = false;
        isOutbound = message == message.getExchange().getOutMessage()
                || message == message.getExchange().getOutFaultMessage();

        if (isOutbound) {
            OutputStream os = message.getContent(OutputStream.class);

            CachedStream cs = new CachedStream();
            message.setContent(OutputStream.class, cs);

            message.getInterceptorChain().doIntercept(message);

            try {
                cs.flush();
                IOUtils.closeQuietly(cs);
                CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);

                String currentEnvelopeMessage = IOUtils.toString(csnew.getInputStream(), "UTF-8");
                csnew.flush();
                IOUtils.closeQuietly(csnew);

                if (getLogger().isDebugEnabled()) {
                    getLogger().debug("Outbound message: " + currentEnvelopeMessage);
                }

                String res = changeOutboundMessage(currentEnvelopeMessage);
                if (res != null) {
                    if (getLogger().isDebugEnabled()) {
                        getLogger().debug("Outbound message has been changed: " + res);
                    }
                }
                res = res != null ? res : currentEnvelopeMessage;

                InputStream replaceInStream = IOUtils.toInputStream(res, "UTF-8");

                IOUtils.copy(replaceInStream, os);
                replaceInStream.close();
                IOUtils.closeQuietly(replaceInStream);

                os.flush();
                message.setContent(OutputStream.class, os);
                IOUtils.closeQuietly(os);

            } catch (IOException ioe) {
                getLogger().warn("Unable to perform change.", ioe);
                throw new RuntimeException(ioe);
            }
        } else {
            try {
                InputStream is = message.getContent(InputStream.class);
                String currentEnvelopeMessage = IOUtils.toString(is, "UTF-8");
                IOUtils.closeQuietly(is);

                if (getLogger().isDebugEnabled()) {
                    getLogger().debug("Inbound message: " + currentEnvelopeMessage);
                }

                String res = changeInboundMessage(currentEnvelopeMessage);
                if (res != null) {
                    if (getLogger().isDebugEnabled()) {
                        getLogger().debug("Inbound message has been changed: " + res);
                    }
                }
                res = res != null ? res : currentEnvelopeMessage;

                is = IOUtils.toInputStream(res, "UTF-8");
                message.setContent(InputStream.class, is);
                IOUtils.closeQuietly(is);
            } catch (IOException ioe) {
                getLogger().warn("Unable to perform change.", ioe);

                throw new RuntimeException(ioe);
            }
        }
    }

    public void handleFault(Message message) {
    }

    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 {
        }
    }
}

Based on the first comment, I created an abstract class which can easily be used to change the whole soap envelope.

Just in case someone wants a ready-to-use code part.

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

import org.apache.commons.io.IOUtils;
import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor;
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.log4j.Logger;

/**
 * http://www.mastertheboss.com/jboss-web-services/apache-cxf-interceptors
 * http://stackoverflow.com/questions/6915428/how-to-modify-the-raw-xml-message-of-an-outbound-cxf-request
 * 
 */
public abstract class MessageChangeInterceptor extends AbstractPhaseInterceptor<Message> {

    public MessageChangeInterceptor() {
        super(Phase.PRE_STREAM);
        addBefore(SoapPreProtocolOutInterceptor.class.getName());
    }

    protected abstract Logger getLogger();

    protected abstract String changeOutboundMessage(String currentEnvelope);

    protected abstract String changeInboundMessage(String currentEnvelope);

    public void handleMessage(Message message) {
        boolean isOutbound = false;
        isOutbound = message == message.getExchange().getOutMessage()
                || message == message.getExchange().getOutFaultMessage();

        if (isOutbound) {
            OutputStream os = message.getContent(OutputStream.class);

            CachedStream cs = new CachedStream();
            message.setContent(OutputStream.class, cs);

            message.getInterceptorChain().doIntercept(message);

            try {
                cs.flush();
                IOUtils.closeQuietly(cs);
                CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);

                String currentEnvelopeMessage = IOUtils.toString(csnew.getInputStream(), "UTF-8");
                csnew.flush();
                IOUtils.closeQuietly(csnew);

                if (getLogger().isDebugEnabled()) {
                    getLogger().debug("Outbound message: " + currentEnvelopeMessage);
                }

                String res = changeOutboundMessage(currentEnvelopeMessage);
                if (res != null) {
                    if (getLogger().isDebugEnabled()) {
                        getLogger().debug("Outbound message has been changed: " + res);
                    }
                }
                res = res != null ? res : currentEnvelopeMessage;

                InputStream replaceInStream = IOUtils.toInputStream(res, "UTF-8");

                IOUtils.copy(replaceInStream, os);
                replaceInStream.close();
                IOUtils.closeQuietly(replaceInStream);

                os.flush();
                message.setContent(OutputStream.class, os);
                IOUtils.closeQuietly(os);

            } catch (IOException ioe) {
                getLogger().warn("Unable to perform change.", ioe);
                throw new RuntimeException(ioe);
            }
        } else {
            try {
                InputStream is = message.getContent(InputStream.class);
                String currentEnvelopeMessage = IOUtils.toString(is, "UTF-8");
                IOUtils.closeQuietly(is);

                if (getLogger().isDebugEnabled()) {
                    getLogger().debug("Inbound message: " + currentEnvelopeMessage);
                }

                String res = changeInboundMessage(currentEnvelopeMessage);
                if (res != null) {
                    if (getLogger().isDebugEnabled()) {
                        getLogger().debug("Inbound message has been changed: " + res);
                    }
                }
                res = res != null ? res : currentEnvelopeMessage;

                is = IOUtils.toInputStream(res, "UTF-8");
                message.setContent(InputStream.class, is);
                IOUtils.closeQuietly(is);
            } catch (IOException ioe) {
                getLogger().warn("Unable to perform change.", ioe);

                throw new RuntimeException(ioe);
            }
        }
    }

    public void handleFault(Message message) {
    }

    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 {
        }
    }
}
怕倦 2024-12-04 16:20:42

我今天也遇到这个问题了。经过多次哭泣和咬牙切齿之后,我能够更改 configuration_interceptor 演示:

OutputStream os = message.getContent(OutputStream.class);
CachedStream cs = new CachedStream();
message.setContent(OutputStream.class, cs);

message.getInterceptorChain().doIntercept(message);

try {
    cs.flush();
    CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);

    String soapMessage = IOUtils.toString(csnew.getInputStream());
    ...

soapMessage 变量将包含完整的 SOAP 消息。您应该能够操作肥皂消息,将其刷新到输出流并执行 message.setContent(OutputStream.class... 调用以对消息进行修改。这没有任何保证,因为我自己对 CXF 还很陌生!

注意:CachedStream 是 StreamInterceptor 类中的私有类,不要忘记将拦截器配置为在 PRE_STREAM 阶段运行,以便 SOAP 拦截器有机会编写 SOAP。 信息。

I had this problem as well today. After much weeping and gnashing of teeth, I was able to alter the StreamInterceptor class in the configuration_interceptor demo that comes with the CXF source:

OutputStream os = message.getContent(OutputStream.class);
CachedStream cs = new CachedStream();
message.setContent(OutputStream.class, cs);

message.getInterceptorChain().doIntercept(message);

try {
    cs.flush();
    CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);

    String soapMessage = IOUtils.toString(csnew.getInputStream());
    ...

The soapMessage variable will contain the complete SOAP message. You should be able to manipulate the soap message, flush it to an output stream and do a message.setContent(OutputStream.class... call to put your modifications on the message. This comes with no warranty, since I'm pretty new to CXF myself!

Note: CachedStream is a private class in the StreamInterceptor class. Don't forget to configure your interceptor to run in the PRE_STREAM phase so that the SOAP interceptors have a chance to write the SOAP message.

奶茶白久 2024-12-04 16:20:42

以下能够冒泡服务器端异常。在之前的解决方案中使用 os.close() 而不是 IOUtils.closeQuietly(os) 也能够引发异常。

public class OutInterceptor extends AbstractPhaseInterceptor<Message> {     
    public OutInterceptor() { 
        super(Phase.PRE_STREAM); 
        addBefore(StaxOutInterceptor.class.getName()); 
    }   
    public void handleMessage(Message message) { 
        OutputStream os = message.getContent(OutputStream.class); 
        CachedOutputStream cos = new CachedOutputStream(); 
        message.setContent(OutputStream.class, cos); 
        message.getInterceptorChain.aad(new PDWSOutMessageChangingInterceptor(os)); 
    }
} 

public class OutMessageChangingInterceptor extends AbstractPhaseInterceptor<Message> {
    private OutputStream os; 

    public OutMessageChangingInterceptor(OutputStream os){
        super(Phase.PRE_STREAM_ENDING); 
        addAfter(StaxOutEndingInterceptor.class.getName()); 
        this.os = os;
    } 

    public void handleMessage(Message message) { 
        try { 
            CachedOutputStream csnew = (CachedOutputStream) message .getContent(OutputStream.class);
            String currentEnvelopeMessage = IOUtils.toString( csnew.getInputStream(), (String) message.get(Message.ENCODING)); 
            csnew.flush(); 
            IOUtils.closeQuietly(csnew); 
            String res = changeOutboundMessage(currentEnvelopeMessage); 
            res = res != null ? res : currentEnvelopeMessage; 
            InputStream replaceInStream = IOUtils.tolnputStream(res, (String) message.get(Message.ENCODING)); 
            IOUtils.copy(replaceInStream, os); 
            replaceInStream.close(); 
            IOUtils.closeQuietly(replaceInStream);
            message.setContent(OutputStream.class, os);
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);  
        }
    }
} 

Following is able to bubble up server side exceptions. Use of os.close() instead of IOUtils.closeQuietly(os) in previous solution is also able to bubble up exceptions.

public class OutInterceptor extends AbstractPhaseInterceptor<Message> {     
    public OutInterceptor() { 
        super(Phase.PRE_STREAM); 
        addBefore(StaxOutInterceptor.class.getName()); 
    }   
    public void handleMessage(Message message) { 
        OutputStream os = message.getContent(OutputStream.class); 
        CachedOutputStream cos = new CachedOutputStream(); 
        message.setContent(OutputStream.class, cos); 
        message.getInterceptorChain.aad(new PDWSOutMessageChangingInterceptor(os)); 
    }
} 

public class OutMessageChangingInterceptor extends AbstractPhaseInterceptor<Message> {
    private OutputStream os; 

    public OutMessageChangingInterceptor(OutputStream os){
        super(Phase.PRE_STREAM_ENDING); 
        addAfter(StaxOutEndingInterceptor.class.getName()); 
        this.os = os;
    } 

    public void handleMessage(Message message) { 
        try { 
            CachedOutputStream csnew = (CachedOutputStream) message .getContent(OutputStream.class);
            String currentEnvelopeMessage = IOUtils.toString( csnew.getInputStream(), (String) message.get(Message.ENCODING)); 
            csnew.flush(); 
            IOUtils.closeQuietly(csnew); 
            String res = changeOutboundMessage(currentEnvelopeMessage); 
            res = res != null ? res : currentEnvelopeMessage; 
            InputStream replaceInStream = IOUtils.tolnputStream(res, (String) message.get(Message.ENCODING)); 
            IOUtils.copy(replaceInStream, os); 
            replaceInStream.close(); 
            IOUtils.closeQuietly(replaceInStream);
            message.setContent(OutputStream.class, os);
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);  
        }
    }
} 
苯莒 2024-12-04 16:20:42

基于 这个

package kz.bee.bip;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

public class SOAPOutboundInterceptor extends AbstractPhaseInterceptor<Message> {

    public SOAPOutboundInterceptor() {
        super(Phase.PRE_STREAM);
        addBefore(SoapPreProtocolOutInterceptor.class.getName());
    }

    public void handleMessage(Message message) {

        boolean isOutbound = false;
        isOutbound = message == message.getExchange().getOutMessage()
                || message == message.getExchange().getOutFaultMessage();

        if (isOutbound) {
            OutputStream os = message.getContent(OutputStream.class);
            CachedStream cs = new CachedStream();
            message.setContent(OutputStream.class, cs);

            message.getInterceptorChain().doIntercept(message);

            try {
                cs.flush();
                IOUtils.closeQuietly(cs);
                CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);

                String currentEnvelopeMessage = IOUtils.toString(csnew.getInputStream(), "UTF-8");
                csnew.flush();
                IOUtils.closeQuietly(csnew);

                /* here we can set new data instead of currentEnvelopeMessage*/
                InputStream replaceInStream = IOUtils.toInputStream(currentEnvelopeMessage, "UTF-8");

                IOUtils.copy(replaceInStream, os);
                replaceInStream.close();
                IOUtils.closeQuietly(replaceInStream);

                os.flush();
                message.setContent(OutputStream.class, os);
                IOUtils.closeQuietly(os);
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }

    public void handleFault(Message message) {
    }

    private static class CachedStream extends CachedOutputStream {
        public CachedStream() {
            super();
        }

        protected void doFlush() throws IOException {
            currentStream.flush();
        }

        protected void doClose() throws IOException {
        }

        protected void onWrite() throws IOException {
        }
    }
}

Good example for replacing outbound soap content based on this

package kz.bee.bip;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

public class SOAPOutboundInterceptor extends AbstractPhaseInterceptor<Message> {

    public SOAPOutboundInterceptor() {
        super(Phase.PRE_STREAM);
        addBefore(SoapPreProtocolOutInterceptor.class.getName());
    }

    public void handleMessage(Message message) {

        boolean isOutbound = false;
        isOutbound = message == message.getExchange().getOutMessage()
                || message == message.getExchange().getOutFaultMessage();

        if (isOutbound) {
            OutputStream os = message.getContent(OutputStream.class);
            CachedStream cs = new CachedStream();
            message.setContent(OutputStream.class, cs);

            message.getInterceptorChain().doIntercept(message);

            try {
                cs.flush();
                IOUtils.closeQuietly(cs);
                CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);

                String currentEnvelopeMessage = IOUtils.toString(csnew.getInputStream(), "UTF-8");
                csnew.flush();
                IOUtils.closeQuietly(csnew);

                /* here we can set new data instead of currentEnvelopeMessage*/
                InputStream replaceInStream = IOUtils.toInputStream(currentEnvelopeMessage, "UTF-8");

                IOUtils.copy(replaceInStream, os);
                replaceInStream.close();
                IOUtils.closeQuietly(replaceInStream);

                os.flush();
                message.setContent(OutputStream.class, os);
                IOUtils.closeQuietly(os);
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }

    public void handleFault(Message message) {
    }

    private static class CachedStream extends CachedOutputStream {
        public CachedStream() {
            super();
        }

        protected void doFlush() throws IOException {
            currentStream.flush();
        }

        protected void doClose() throws IOException {
        }

        protected void onWrite() throws IOException {
        }
    }
}

乖乖 2024-12-04 16:20:42

更好的方法是使用 DOM 接口修改消息,您需要首先添加 SAAJOutInterceptor (这可能会对大请求产生性能影响),然后在 USER_PROTOCOL 阶段执行的自定义拦截器

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Node;

import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

abstract public class SoapNodeModifierInterceptor extends AbstractSoapInterceptor {
    SoapNodeModifierInterceptor() { super(Phase.USER_PROTOCOL); }

    @Override public void handleMessage(SoapMessage message) throws Fault {
        try {
            if (message == null) {
                return;
            }
            SOAPMessage sm = message.getContent(SOAPMessage.class);
            if (sm == null) {
                throw new RuntimeException("You must add the SAAJOutInterceptor to the chain");
            }

            modifyNodes(sm.getSOAPBody());

        } catch (SOAPException e) {
            throw new RuntimeException(e);
        }
    }

    abstract void modifyNodes(Node node);
}

a better way would be to modify the message using the DOM interface, you need to add the SAAJOutInterceptor first (this might have a performance hit for big requests) and then your custom interceptor that is executed in phase USER_PROTOCOL

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Node;

import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

abstract public class SoapNodeModifierInterceptor extends AbstractSoapInterceptor {
    SoapNodeModifierInterceptor() { super(Phase.USER_PROTOCOL); }

    @Override public void handleMessage(SoapMessage message) throws Fault {
        try {
            if (message == null) {
                return;
            }
            SOAPMessage sm = message.getContent(SOAPMessage.class);
            if (sm == null) {
                throw new RuntimeException("You must add the SAAJOutInterceptor to the chain");
            }

            modifyNodes(sm.getSOAPBody());

        } catch (SOAPException e) {
            throw new RuntimeException(e);
        }
    }

    abstract void modifyNodes(Node node);
}
断念 2024-12-04 16:20:42

这个为我工作。它基于 Apache CXF 示例中的 configuration_interceptor 示例中的 StreamInterceptor 类。

它使用的是 Scala 而不是 Java,但转换非常简单。

我尝试添加评论来解释发生的事情(据我所知)。

import java.io.OutputStream

import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor
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

// java note: base constructor call is hidden at the end of class declaration
class StreamInterceptor() extends AbstractPhaseInterceptor[Message](Phase.PRE_STREAM) {

  // java note: put this into the constructor after calling super(Phase.PRE_STREAM);
  addBefore(classOf[SoapPreProtocolOutInterceptor].getName)

  override def handleMessage(message: Message) = {
    // get original output stream
    val osOrig = message.getContent(classOf[OutputStream])
    // our output stream
    val osNew = new CachedOutputStream
    // replace it with ours
    message.setContent(classOf[OutputStream], osNew)
    // fills the osNew instead of osOrig
    message.getInterceptorChain.doIntercept(message)
    // flush before getting content
    osNew.flush()
    // get filled content
    val content = IOUtils.toString(osNew.getInputStream, "UTF-8")
    // we got the content, we may close our output stream now
    osNew.close()
    // modified content
    val modifiedContent = content.replace("a-string", "another-string")
    // fill original output stream
    osOrig.write(modifiedContent.getBytes("UTF-8"))
    // flush before set
    osOrig.flush()
    // replace with original output stream filled with our modified content
    message.setContent(classOf[OutputStream], osOrig)
  }
}

this one's working for me. It's based on StreamInterceptor class from configuration_interceptor example in Apache CXF samples.

It's in Scala instead of Java but the conversion is straightforward.

I tried to add comments to explain what's happening (as far as I understand).

import java.io.OutputStream

import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor
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

// java note: base constructor call is hidden at the end of class declaration
class StreamInterceptor() extends AbstractPhaseInterceptor[Message](Phase.PRE_STREAM) {

  // java note: put this into the constructor after calling super(Phase.PRE_STREAM);
  addBefore(classOf[SoapPreProtocolOutInterceptor].getName)

  override def handleMessage(message: Message) = {
    // get original output stream
    val osOrig = message.getContent(classOf[OutputStream])
    // our output stream
    val osNew = new CachedOutputStream
    // replace it with ours
    message.setContent(classOf[OutputStream], osNew)
    // fills the osNew instead of osOrig
    message.getInterceptorChain.doIntercept(message)
    // flush before getting content
    osNew.flush()
    // get filled content
    val content = IOUtils.toString(osNew.getInputStream, "UTF-8")
    // we got the content, we may close our output stream now
    osNew.close()
    // modified content
    val modifiedContent = content.replace("a-string", "another-string")
    // fill original output stream
    osOrig.write(modifiedContent.getBytes("UTF-8"))
    // flush before set
    osOrig.flush()
    // replace with original output stream filled with our modified content
    message.setContent(classOf[OutputStream], osOrig)
  }
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文