This is definitely a bug for whomever is consuming that message.   
According to the XML rules, both messages are equivilent.

Couple options:

1) Best performing option:  write an interceptor that would be 
immediately AFTER the StaxOutInterceptor that would take the 
XMLStreamWriter and replace it with a new XMLStreamWriter that wrappers 
the original, but overwrides the start element and namespace map stuff 
so that it generates empty prefixes at all times.  That StreamWriter 
might be a bit tricky to write if you aren't familliar with StAX, but it 
would definitely be the best performing as you wouln't break the 
streaming, you wouldn't need to scan the byte[], etc....  FYI: your 
interceptor will also need to set:
msg.put(AbstractOutDatabindingInterceptor.DISABLE_OUTPUTSTREAM_OPTIMIZATION,
        Boolean.TRUE);
to make sure it actually uses the new StreamWriter in all cases.


2) Next option: your CachedOutputStream stuff.....   This actually will 
work, but you need to modify things a bit.  First off, it needs to be 
split into two interceptors: (usually, it's one interceptor.java that 
then has an inner class for the other.  See the AttachmentOutInterceptor 
for example)
   a) First/Outer one will replace the OutputStream with the cached 
output stream and record the original stream.   It will also then add 
the second one to the chain. Make sure it's stuck before the attachement 
stuff:
        super(Phase.PRE_STREAM);
        addBefore(AttachmentOutInterceptor.class.getName());

   b) The second/inner interceptor would grab the Cached stream, do the 
transformation, and flush back to original stream.   It would be:
   super(Phase.PRE_STREAM_ENDING);
   addAfter(AttachmentOutInterceptor.AttachmentOutEndingInterceptor
               .class.getName());

Dan




On Thursday 20 March 2008, Yuval Zou wrote:
> Hi,
>
> Recently, I'm working on a web services client using CXF. But some
> request messages can't be parsed by the web services server. I found
> the problem is related to the namespace and prefix.
> The correct message:
> <?xml version="1.0" encoding="UTF-8"?>
> <CreateItemRequest
> xmlns="http://www.ibm.com/xmlns/db2/cm/beans/1.0/schema";>
> <AuthenticationData>
>   <ServerDef>
>    <ServerName>icmnlsdb</ServerName>
>   </ServerDef>
>   <LoginData>
>    <UserID>icmadmin</UserID>
>    <Password>********</Password>
>   </LoginData>
>  </AuthenticationData>
>  <Item>
>   <ItemXML>
>    <CLAIM_1047 DATE_1047="2004-01-27" CLAIMNO_1047="1234"
> DESC_1047="This is a claim regarding the accident.3">
>     <properties xmlns="http://www.ibm.com/xmlns/db2/cm/api/1.0/schema";
> type="document"/>
>     <VEHICLE_1047 VIN_1047="38">
>      <OWNER_1047 FNAME_1047="Ben" LNAME_1047="Dover"/>
>      <OWNER_1047 FNAME_1047="Eileen" LNAME_1047="Dover"/>
>     </VEHICLE_1047>
>     <VEHICLE_1047 VIN_1047="34">
>      <OWNER_1047 FNAME_1047="I.P." LNAME_1047="Freely"/>
>     </VEHICLE_1047>
>     <ICMBASE>
>      <resourceObject
> xmlns="http://www.ibm.com/xmlns/db2/cm/api/1.0/schema";
> MIMEType="image/tiff">
>       <label name="base 1"/>
>      </resourceObject>
>     </ICMBASE>
>    </CLAIM_1047>
>   </ItemXML>
>  </Item>
> </CreateItemRequest>
> The namespace http://www.ibm.com/xmlns/db2/cm/api/1.0/schema was put
> in the element that needs it in this correct message.
>
> The mesage can't be parsed by server (sent by CXF):
> <?xml version="1.0" encoding="UTF-8"?>
> <CreateItemRequest
> xmlns:ns2="http://www.ibm.com/xmlns/db2/cm/api/1.0/schema";
> xmlns="http://www.ibm.com/xmlns/db2/cm/beans/1.0/schema";>
>  <AuthenticationData>
>   <ServerDef>
>    <ServerName>icmnlsdb</ServerName>
>   </ServerDef>
>   <LoginData>
>    <UserID>icmadmin</UserID>
>    <Password>********</Password>
>   </LoginData>
>  </AuthenticationData>
>  <Item>
>   <ItemXML>
>    <CLAIM_1047 DESC_1047="This is a claim regarding the accident.3"
> CLAIMNO_1047="1234" DATE_1047="2004-01-27">
>     <ns2:properties type="document"/>
>     <VEHICLE_1047 VIN_1047="38">
>      <OWNER_1047 LNAME_1047="Dover" FNAME_1047="Ben"/>
>      <OWNER_1047 LNAME_1047="Dover" FNAME_1047="Eileen"/>
>     </VEHICLE_1047>
>     <VEHICLE_1047 VIN_1047="34">
>      <OWNER_1047 LNAME_1047="Freely" FNAME_1047="I.P."/>
>     </VEHICLE_1047>
>     <ICMBASE>
>      <ns2:resourceObject MIMEType="image/tiff">
>       <ns2:label name="base 1"/>
>      </ns2:resourceObject>
>     </ICMBASE>
>    </CLAIM_1047>
>   </ItemXML>
>  </Item>
> </CreateItemRequest>
>
> The namespace http://www.ibm.com/xmlns/db2/cm/api/1.0/schema was put
> in the root element.
>
> Is there anyone who knows how to configure CXF to generate the XML
> message in accordance with the first style? Or is there possible to
> manually modify the generated message using out Interceptor?
> Actually, I have tried to use interceptor the modify the output
> stream: public StreamInterceptor() {
>         super(Phase.PRE_STREAM);
>         addBefore(SoapPreProtocolOutInterceptor.class.getName());
> }
>
>    public void handleMessage(Message message) {
>      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);
> //            FileOutputStream fileOut = new
> FileOutputStream("D:\\test.txt");
> //            CachedOutputStream.copyStream(csnew.getInputStream(),
> fileOut, 1024);
>
>             StringBuilder sb = new StringBuilder();
>             csnew.writeCacheTo(sb);
>
>             String tmpXML = sb.toString();
>             System.out.println("#####OLD####" + tmpXML);
>             while (tmpXML.indexOf("<ns2:")!=-1){
>              String subTmp =
> tmpXML.substring(tmpXML.indexOf("<ns2:")); subTmp =
> subTmp.substring(1, subTmp.indexOf(" ")); tmpXML =
> tmpXML.replaceAll(subTmp, subTmp.substring(4) + " " +
> "xmlns=\"http://www.ibm.com/xmlns/db2/cm/api/1.0/schema\<http://www.ib
>m.com/xmlns/db2/cm/api/1.0/schema/>" ");
>              System.out.println("#####FIXED#######" + tmpXML);
>             }
>
>             InputStream in = new
> ByteArrayInputStream(tmpXML.getBytes());
>
>             BufferedOutputStream bos = new BufferedOutputStream(os);
>             CachedOutputStream.copyStream(in, bos, 1024);
>
>             cs.close();
>             in.close();
> //            fileOut.close();
>             bos.close();
>             os.flush();
>
>             message.setContent(OutputStream.class, os);
>         } catch (IOException ioe) {
>             ioe.printStackTrace();
>         }
>     }
>
> But the above code can't handle the message stream with MTOM
> attachements. It can't get the OutputStream at all. I don't know the
> reason.
>
> Your help will be really appreciated. Thanks in advance!
> Yuval Zou



-- 
J. Daniel Kulp
Principal Engineer, IONA
[EMAIL PROTECTED]
http://www.dankulp.com/blog

Reply via email to