如何在CXF中使用Transform删除入站XML元素? [英] How do I drop an inbound XML element with a Transform in CXF?

查看:92
本文介绍了如何在CXF中使用Transform删除入站XML元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用MS Exchange Web服务(EWS)的客户端中使用CXF(v2.7.10).

我发现EWS(UniqueHash)返回的元素之一包含在XML v1.0中无效的字符.由于对此我无能为力,因此我尝试使用入站拦截器来删除UniqueHash元素(我不需要它们),如下所示:

  Map< String,String>inTransformMap = Collections.singletonMap("{http://schemas.microsoft.com/exchange/services/2006/types}UniqueHash",");TransformInInterceptor transformInInterceptor = new TransformInInterceptor();transformInInterceptor.setInTransformElements(inTransformMap);client.getInInterceptors().add(transformInInterceptor); 

我可以看到转换(TransformInInterceptor)运行得很好并且很早(后流):

  FINE:创建链org.apache.cxf.phase.PhaseInterceptorChain@be78549.电流:接收[PolicyInInterceptor,LoggingInInterceptor,AttachmentInInterceptor]后流[TransformInInterceptor,StaxInInterceptor]阅读[WSDLGetInterceptor,ReadHeadersInterceptor,SoapActionInInterceptor,StartBodyInterceptor]协议前[MustUnderstandInterceptor]协议后[CheckFaultInterceptor,JAXBAttachmentSchemaValidationHack]解组[DocLiteralInInterceptor,SoapHeaderInterceptor]后逻辑[WrapperClassInInterceptor]预调用[SwAInInterceptor,HolderInInterceptor] 

但是,即使它看起来像按预期的那样正常工作以逐步执行代码,当DocLiteralInInterceptor稍后触发时,它也会抛出此编组错误(在这种情况下,0x4在我认为我会使用的UniqueHash元素内删除):

  org.apache.cxf.interceptor.Fault:编组错误:非法字符实体:扩展字符(代码0x4在[row,col {unknown-source}]:[1,2230]在org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:881)在org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:702)在org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:160)在org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:192)在org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)在org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:835)在org.apache.cxf.transport.http.HTTPConduit $ WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1614)在org.apache.cxf.transport.http.HTTPConduit $ WrappedOutputStream.handleResponse(HTTPConduit.java:1504)在org.apache.cxf.transport.http.HTTPConduit $ WrappedOutputStream.close(HTTPConduit.java:1310)在org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit $ AsyncWrappedOutputStream.close(AsyncHTTPConduit.java:381)在org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:50)在org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:223)在org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)在org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:628)在org.apache.cxf.interceptor.MessageSenderInterceptor $ MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)在org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)在org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:565)在org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)在org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377)在org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330)在org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)在org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)在com.sun.proxy.$ Proxy67.searchMailboxes(来源不明)引起原因:javax.xml.bind.UnmarshalException 

这是我正在使用的XML响应:

 <?xml version ="1.0" encoding ="utf-8"?>< s:信封xmlns:s ="http://schemas.xmlsoap.org/soap/envelope/">< s:Header>< h:ServerVersionInfo MajorVersion ="15" MinorVersion ="0" MajorBuildNumber ="847" MinorBuildNumber ="31" Version ="V2_8" xmlns:h ="http://schemas.microsoft.com/exchange/services/2006/types"xmlns =" http://schemas.microsoft.com/exchange/services/2006/types"xmlns:xsd =" http://www.w3.org/2001/XMLSchema"xmlns:xsi =" http://www.w3.org/2001/XMLSchema-instance"/></s:Header>< s:正文xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd ="http://www.w3.org/2001/XMLSchema">< m:SearchMailboxesResponse xmlns:m ="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t ="http://schemas.microsoft.com/exchange/services/2006/types>< m:ResponseMessages>< m:SearchMailboxesResponseMessage ResponseClass ="Success">< m:ResponseCode> NoError</m:ResponseCode>< m:SearchMailboxesResult>< t:SearchQueries>< t:MailboxQuery>< t:Query>一般宿舍"</t:Query>< t:MailboxSearchScopes>< t:MailboxSearchScope>< t:Mailbox>/o =第一组织/ou = Exchange管理组(FYDIBOHF23SPDLT)/cn =收件人/cn = 6f8abfc1a1694cf299c7b3ae5522d8c4-John</t:Mailbox>< t:SearchScope>全部</t:SearchScope></t:MailboxSearchScope></t:MailboxSearchScopes></t:MailboxQuery></t:SearchQueries>< t:ResultType>仅预览</t:ResultType>< t:ItemCount> 1</t:ItemCount>< t:Size> 3169</t:Size>< t:PageItemCount> 1</t:PageItemCount>< t:PageItemSize> 3169</t:PageItemSize>< t:Items>< t:SearchPreviewItem>< T:的ID = AAMkADY4MDY1MWViLTMzMWItNDEyYi1iMjUzLTQ2ZjMwNWVkYmIzYQBGAAAAAABkY13xq9IqS5OySCQXk7W3BwC9AjA7QbibQa9DQZUO2Dm3AAAAAAAMAAC9AjA7QbibQa9DQZUO2Dm3AAAE/bU4AAA =" ChangeKey = CQAAABYAAAC9AjA7QbibQa9DQZUO2Dm3AAAE/CEM"/>< t:Mailbox>< t:MailboxId>/o =第一组织/ou = Exchange管理组(FYDIBOHF23SPDLT)/cn =收件人/cn = 6f8abfc1a1694cf299c7b3ae5522d8c4-John</t:MailboxId>< t:PrimarySmtpAddress> john.smith@internal.local</t:PrimarySmtpAddress></t:邮箱>< t:ParentId Id ="AQMkADY4MDY1MWViLTMzADFiLTQxMmItYjI1My00NmYzMDVlZGJiADNhAC4AAANkY13xq9IqS5OySCQXk7W3AQC9AjA7QbibQA9A = DQZUO2 = AAA< t:ItemClass> IPM.注意</t:ItemClass>< t:UniqueHash> 00036& lt; 0788d814ffea4e499c2fdb479c8617a2@ex01.internal.local> 0010General Quarters000C&#x4;&#x0;&#x0;&#x0;?&#x19;"#x10;&#x12; {& #xB;&#x17;</t:UniqueHash>< t:SortValue> 001B2014-03-11T19:42:42.00000000000006F00001182</t:SortValue>< T:OwaLink> HTTPS://ex01.internal.local/owa/integrated/视图模型= ItemReadingPaneViewModelPopOutFactory&放大器;放大器; IsDiscoveryView = 1&放大器;放大器; exsvurl = 1&放大器;放大器;的ItemID = AAMkADY4MDY1MWViLTMzMWItNDEyYi1iMjUzLTQ2ZjMwNWVkYmIzYQBGAAAAAABkY13xq9IqS5OySCQXk7W3BwC9AjA7QbibQa9DQZUO2Dm3AAAAAAAMAAC9AjA7QbibQa9DQZUO2Dm3AAAE%2FbU4AAA%3D</吨?:OwaLink>< t:Sender>约翰·史密斯</t:Sender>< t:ToRecipients>< t:SmtpAddress>我们的共享邮箱</t:SmtpAddress></t:ToRecipients>< t:CreatedTime> 2014-03-11T19:42:42Z</t:CreatedTime>< t:ReceivedTime> 2014-03-11T19:42:42Z</t:ReceivedTime>< t:SentTime> 2014-03-11T19:42:42Z</t:SentTime>< t:主题>一般宿舍</t:主题>< t:Size> 3169</t:Size>< t:预览/>< t:重要性>正常</t:重要性>< t:Read> true</t:Read>< t:HasAttachment> false</t:HasAttachment></t:SearchPreviewItem></t:Items>< t:MailboxStats>< t:MailboxStat>< t:MailboxId>/o =第一组织/ou = Exchange管理组(FYDIBOHF23SPDLT)/cn =收件人/cn = 6f8abfc1a1694cf299c7b3ae5522d8c4-John</t:MailboxId>< t:DisplayName>约翰·史密斯</t:DisplayName>< t:ItemCount> 1</t:ItemCount>< t:Size> 3169</t:Size></t:MailboxStat></t:MailboxStats></m:SearchMailboxesResult></m:SearchMailboxesResponseMessage></m:ResponseMessages></m:SearchMailboxesResponse></s:Body></s:信封> 

有人知道我在做什么错吗?关于我如何摆脱该元素及其麻烦内容的任何指示?

解决方案

解决了这个问题(感谢Daniel Kulp通过cxf用户邮件列表进行确认).

问题是 InTransformReader 扩展了 DepthXMLStreamReader .这意味着即使我试图删除或替换无效字符, TransformInInterceptor 仍将首先尝试尝试将它们反编组.

解决方案是在调用 StaxInInterceptor 之前,在PRE_STREAM阶段创建一个扩展了 AbstractPhaseInterceptor 的新拦截器,并使用正则表达式过滤掉无效文本.>

一旦知道如何就轻松!

示例:

以下内容将从肥皂消息中删除无效的XML字符:

  import org.apache.cxf.interceptor.Fault;导入org.apache.cxf.message.Message;导入org.apache.cxf.phase.AbstractPhaseInterceptor;导入org.apache.cxf.phase.Phase;导入java.io.IOException;导入java.io.InputStream;导入java.io.OutputStream;导入org.apache.commons.io.IOUtils;导入org.apache.cxf.io.CachedOutputStream;公共类InvalidCharInterceptor扩展AbstractPhaseInterceptor< Message>.{公共InvalidCharInterceptor(){超级(Phase.PRE_STREAM);}/***从xml规范中获取有效字符:< br>*#x9 |#xA |#xD |[#x20-#xD7FF] |[#xE000-#xFFFD] |[#x10000-#x10FFFF]< br>*任何Unicode字符,但不包括代理块FFFE和FFFF.** @param文字*要清洁的琴弦* @参数替换*每次比赛要替换的字符串* @return结果字符串*/公共静态字符串cleanInvalidXmlChars(字符串文本,字符串替换){字符串re ="[^ \\ x09 \\ x0A \\ x0D \\ x20-\\ xD7FF \\ xE000-\\ xFFFD \\ x10000-x10FFFF]";返回text.replaceAll(re,replace);}@Override公共无效handleMessage(消息)引发故障{boolean isOutbound = false;isOutbound =消息== message.getExchange().getOutMessage()||消息== message.getExchange().getOutFaultMessage();如果(isOutbound){OutputStream os = message.getContent(OutputStream.class);CachedOutputStream cs = new CachedOutputStream();message.setContent(OutputStream.class,cs);message.getInterceptorChain().doIntercept(message);尝试 {cs.flush();IOUtils.closeQuietly(cs);CachedOutputStream csnew =(CachedOutputStream)message.getContent(OutputStream.class);字符串currentEnvelopeMessage = IOUtils.toString(csnew.getInputStream(),"UTF-8");csnew.flush();IOUtils.closeQuietly(csnew);字符串res = cleanInvalidXmlChars(currentEnvelopeMessage,");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){抛出新的RuntimeException(ioe);}}}} 

然后将其添加到客户端:

client.getOutInterceptors().add(new InvalidCharInterceptor());

I'm using CXF (v2.7.10) in a client that is consuming the MS Exchange Web Service (EWS).

I'm finding that one of the elements returned by EWS (UniqueHash) contains characters that are invalid in XML v1.0. As I have no control over this I'm trying to use an inbound interceptor to drop the UniqueHash elements (I don't need them) like this:

Map<String, String> inTransformMap = Collections.singletonMap(
        "{http://schemas.microsoft.com/exchange/services/2006/types}UniqueHash", "");
TransformInInterceptor transformInInterceptor = new TransformInInterceptor();
transformInInterceptor.setInTransformElements(inTransformMap);
client.getInInterceptors().add(transformInInterceptor);

I can see that the transform (TransformInInterceptor) is running nice and early (post-stream):

FINE: Chain org.apache.cxf.phase.PhaseInterceptorChain@be78549 was created. Current flow:
  receive [PolicyInInterceptor, LoggingInInterceptor, AttachmentInInterceptor]
  post-stream [TransformInInterceptor, StaxInInterceptor]
  read [WSDLGetInterceptor, ReadHeadersInterceptor, SoapActionInInterceptor, StartBodyInterceptor]
  pre-protocol [MustUnderstandInterceptor]
  post-protocol [CheckFaultInterceptor, JAXBAttachmentSchemaValidationHack]
  unmarshal [DocLiteralInInterceptor, SoapHeaderInterceptor]
  post-logical [WrapperClassInInterceptor]
  pre-invoke [SwAInInterceptor, HolderInInterceptor]

But even though it appears to be working as intended stepping through the code, when DocLiteralInInterceptor fires later on it throws this unmarshalling error (0x4 in this case is within the UniqueHash element I thought I'd dropped):

org.apache.cxf.interceptor.Fault: Unmarshalling Error: Illegal character entity: expansion character (code 0x4
 at [row,col {unknown-source}]: [1,2230] 
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:881)
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:702)
    at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:160)
    at org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:192)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:835)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1614)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1504)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1310)
    at org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit$AsyncWrappedOutputStream.close(AsyncHTTPConduit.java:381)
    at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:50)
    at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:223)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:628)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:565)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
    at com.sun.proxy.$Proxy67.searchMailboxes(Unknown Source)
Caused by: javax.xml.bind.UnmarshalException

Here's the XML response I'm working with:

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15" MinorVersion="0" MajorBuildNumber="847" MinorBuildNumber="31" Version="V2_8" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:SearchMailboxesResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:SearchMailboxesResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:SearchMailboxesResult>
<t:SearchQueries>
<t:MailboxQuery>
<t:Query>"general quarters"</t:Query>
<t:MailboxSearchScopes>
<t:MailboxSearchScope>
<t:Mailbox>/o=First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=6f8abfc1a1694cf299c7b3ae5522d8c4-John</t:Mailbox>
<t:SearchScope>All</t:SearchScope>
</t:MailboxSearchScope>
</t:MailboxSearchScopes>
</t:MailboxQuery>
</t:SearchQueries>
<t:ResultType>PreviewOnly</t:ResultType>
<t:ItemCount>1</t:ItemCount>
<t:Size>3169</t:Size>
<t:PageItemCount>1</t:PageItemCount>
<t:PageItemSize>3169</t:PageItemSize>
<t:Items>
<t:SearchPreviewItem>
<t:Id Id="AAMkADY4MDY1MWViLTMzMWItNDEyYi1iMjUzLTQ2ZjMwNWVkYmIzYQBGAAAAAABkY13xq9IqS5OySCQXk7W3BwC9AjA7QbibQa9DQZUO2Dm3AAAAAAAMAAC9AjA7QbibQa9DQZUO2Dm3AAAE/bU4AAA=" ChangeKey="CQAAABYAAAC9AjA7QbibQa9DQZUO2Dm3AAAE/ceM"/>
<t:Mailbox>
<t:MailboxId>/o=First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=6f8abfc1a1694cf299c7b3ae5522d8c4-John</t:MailboxId>
<t:PrimarySmtpAddress>john.smith@internal.local</t:PrimarySmtpAddress>
</t:Mailbox>
<t:ParentId Id="AQMkADY4MDY1MWViLTMzADFiLTQxMmItYjI1My00NmYzMDVlZGJiADNhAC4AAANkY13xq9IqS5OySCQXk7W3AQC9AjA7QbibQa9DQZUO2Dm3AAADDAAAAA==" ChangeKey="AQAAAA=="/>
<t:ItemClass>IPM.Note</t:ItemClass>
<t:UniqueHash>00036&lt;0788d814ffea4e499c2fdb479c8617a2@ex01.internal.local&gt;0010General Quarters000C&#x4;&#x0;&#x0;&#x0;?&#x19;"&#x10;&#x12;{&#xB;&#x17;</t:UniqueHash>
<t:SortValue>001B2014-03-11T19:42:42.00000000000006F00001182</t:SortValue>
<t:OwaLink>https://ex01.internal.local/owa/integrated/?viewmodel=ItemReadingPaneViewModelPopOutFactory&amp;IsDiscoveryView=1&amp;exsvurl=1&amp;ItemID=AAMkADY4MDY1MWViLTMzMWItNDEyYi1iMjUzLTQ2ZjMwNWVkYmIzYQBGAAAAAABkY13xq9IqS5OySCQXk7W3BwC9AjA7QbibQa9DQZUO2Dm3AAAAAAAMAAC9AjA7QbibQa9DQZUO2Dm3AAAE%2FbU4AAA%3D</t:OwaLink>
<t:Sender>John Smith</t:Sender>
<t:ToRecipients>
<t:SmtpAddress>Our Shared Mailbox</t:SmtpAddress>
</t:ToRecipients>
<t:CreatedTime>2014-03-11T19:42:42Z</t:CreatedTime>
<t:ReceivedTime>2014-03-11T19:42:42Z</t:ReceivedTime>
<t:SentTime>2014-03-11T19:42:42Z</t:SentTime>
<t:Subject>General Quarters</t:Subject>
<t:Size>3169</t:Size>
<t:Preview/>
<t:Importance>Normal</t:Importance>
<t:Read>true</t:Read>
<t:HasAttachment>false</t:HasAttachment>
</t:SearchPreviewItem>
</t:Items>
<t:MailboxStats>
<t:MailboxStat>
<t:MailboxId>/o=First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=6f8abfc1a1694cf299c7b3ae5522d8c4-John</t:MailboxId>
<t:DisplayName>John Smith</t:DisplayName>
<t:ItemCount>1</t:ItemCount>
<t:Size>3169</t:Size>
</t:MailboxStat>
</t:MailboxStats>
</m:SearchMailboxesResult>
</m:SearchMailboxesResponseMessage>
</m:ResponseMessages>
</m:SearchMailboxesResponse>
</s:Body>
</s:Envelope>

Does anyone know what I'm doing wrong here? Any pointers on how I get rid of this element and it's troublesome content?

解决方案

Figured it out (and thanks to Daniel Kulp for confirming it via the cxf users mailing list).

The issue was that the InTransformReader extends DepthXMLStreamReader. This means that even though I was trying to drop or replace invalid characters, the TransformInInterceptor would first attempt to unmarshall them anyway.

The solution was to create a new Interceptor that extended AbstractPhaseInterceptor and filter out the invalid text using a regex during the PRE_STREAM phase, before the StaxInInterceptor was invoked.

Easy once you know how!

Example:

The following will remove invalid XML chars from a soap message:

import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

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

import org.apache.commons.io.IOUtils;
import org.apache.cxf.io.CachedOutputStream;

public class InvalidCharInterceptor extends AbstractPhaseInterceptor<Message> {

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

  /**
   * From xml spec valid chars:<br>
   * #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]<br>
   * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.<br>
   * 
   * @param text
   *          The String to clean
   * @param replacement
   *          The string to be substituted for each match
   * @return The resulting String
   */
  public static String cleanInvalidXmlChars(String text, String replacement) {
    String re = "[^\\x09\\x0A\\x0D\\x20-\\xD7FF\\xE000-\\xFFFD\\x10000-x10FFFF]";
    return text.replaceAll(re, replacement);
  }

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

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

      CachedOutputStream cs = new CachedOutputStream();
      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);

        String res = cleanInvalidXmlChars(currentEnvelopeMessage, "");
        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) {
        throw new RuntimeException(ioe);
      }
    }
  }

}

Then you add it to your client:

client.getOutInterceptors().add(new InvalidCharInterceptor());

这篇关于如何在CXF中使用Transform删除入站XML元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆