Re: How to change the namespace position in the generate xml message (SOAP message)?

2008-03-21 Thread Yuval Zou

Hi Ian,

I have tried your solution but it seems not work as expected. I'm a beginner
of CXF and I'm not sure my implementation is correct. Could you please take
a look at it?
1. I created cxf.xml on the client side:
beans xmlns=http://www.springframework.org/schema/beans;
  xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance;
  xmlns:jaxws=http://cxf.apache.org/jaxws;
  xmlns:soap=http://cxf.apache.org/bindings/soap;
  xsi:schemaLocation=
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/bindings/soap
http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd;
  jaxws:client id=cmwebserviceClient 
serviceClass=cm.webservices.CMWebServicePortType
address=http://localhost/CMBSpecificWebService/services/CMWebService;
jaxws:dataBinding
 bean class=org.apache.cxf.jaxb.JAXBDataBinding
   property name=marshallerProperties
 map
   entry key=com.sun.xml.bind.namespacePrefixMapper
 bean class=common.webservices.NoNamespacePrefixMapper /
   /entry
 /map
   /property
   property name=namespaceMap
map
entry 
key=http://www.ibm.com/xmlns/db2/cm/api/1.0/schema;
valuecm/value
/entry
entry 
key=http://www.ibm.com/xmlns/db2/cm/beans/1.0/schema;
valuecmb/value
/entry
/map
/property
 /bean
   /jaxws:dataBinding
/jaxws:client 
/beans
property name=namespaceMap is insignificant. If it is removed, the
result is same.

2. Implemented the NoNamespacePrefixMapper:
public class NoNamespacePrefixMapper extends
com.sun.xml.bind.marshaller.NamespacePrefixMapper {

@Override
public String getPreferredPrefix(String arg0, String arg1, boolean 
arg2) {
return ;
}

}

3. Get service:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[]{cxf.xml});
return (CMWebServicePortType)context.getBean(cmwebserviceClient);

4. Invoke the service operation. The xml message is still as before.

Is there anything wrong in these steps? Thanks!


ianroberts wrote:
 
 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;
   [snip]
 /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;
   [snip]
 /CreateItemRequest
 
 The namespace http://www.ibm.com/xmlns/db2/cm/api/1.0/schema was put in
 the
 root element.
 
 In XML terms the two messages are exactly the same, so it's more the 
 fault of whatever is parsing the message on the server side rather than 
 of the XML generator in CXF.  Nontheless...
 
 If you're using JAXB databinding then you may be able to do what you 
 want using a custom namespace prefix mapper in the data binding. 
 Something like this (not tested but you get the idea):
 
 jaxws:client ...
jaxws:dataBinding
  bean class=org.apache.cxf.jaxb.JAXBDataBinding
property name=marshallerProperties
  map
entry key=com.sun.xml.bind.namespacePrefixMapper
  bean class=my.package.NoPrefixNamespaceMapper /
/entry
  /map
/property
  /bean
/jaxws:dataBinding
 /jaxws:client
 
 Where NoPrefixNamespaceMapper is an implementation of 
 com.sun.xml.bind.marshaller.NamespacePrefixMapper whose 
 getPreferredPrefix method always returns .  This should force the 
 marshaller to only use prefixes when it absolutely has to.
 
 Ian
 
 -- 
 Ian Roberts   | Department of Computer Science
 [EMAIL PROTECTED]  | University of Sheffield, UK
 
 

-- 
View this message in context: 
http://www.nabble.com/How-to-change-the-namespace-position-in-the-generate-xml-message-%28SOAP-message%29--tp16176819p16194418.html
Sent from the cxf-user mailing list archive at Nabble.com.



Re: How to change the namespace position in the generate xml message (SOAP message)?

2008-03-21 Thread Yuval Zou

Hi Dan,

I have tried the second option. I modified the codes as you suggested. It
works but the attachment data are still embeded in the cached stream. So the
performance of the transformation is terrible. The code looks like below,
could you please help to find if there is something wrong and how can I fix
it? Thank you very much!

public class StreamInterceptor extends AbstractPhaseInterceptor {

private StreamEndingInterceptor ending = new StreamEndingInterceptor();
public static final String ORIGINAL_OUTPUT = original_output; 

public StreamInterceptor() {
super(Phase.PRE_STREAM);
addBefore(AttachmentOutInterceptor.class.getName());
}

public void handleMessage(Message message) {
OutputStream os = message.getContent(OutputStream.class);
message.put(ORIGINAL_OUTPUT, os);
CachedStream cs = new CachedStream();
message.setContent(OutputStream.class, cs);

//  message.getInterceptorChain().doIntercept(message);
try {
cs.flush();
} catch (IOException e) {
e.printStackTrace();
}
message.getInterceptorChain().add(ending);
}

public void handleFault(Message message) {
}

public class StreamEndingInterceptor extends AbstractPhaseInterceptor {

public StreamEndingInterceptor() {
super(Phase.PRE_STREAM_ENDING);

addAfter(AttachmentOutInterceptor.AttachmentOutEndingInterceptor.class.getName());
 
}

public void handleMessage(Message message) {
try {
CachedOutputStream csnew = (CachedOutputStream)
message.getContent(OutputStream.class);
OutputStream os = (OutputStream) 
message.get(ORIGINAL_OUTPUT);

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\; );
System.out.println(#FIXED# + tmpXML);
}   

InputStream in = new 
ByteArrayInputStream(tmpXML.getBytes());   
BufferedOutputStream bos = new BufferedOutputStream(os);
CachedOutputStream.copyStream(in, bos, 1024);

csnew.close();
in.close();
bos.close();
os.flush();

//  message.setContent(OutputStream.class, os);
} catch (IOException e) {
e.printStackTrace();
}
}

}

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

}
}

Yuval
 

dkulp wrote:
 
 
 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 

Re: How to change the namespace position in the generate xml message (SOAP message)?

2008-03-21 Thread Daniel Kulp
On Friday 21 March 2008, Yuval Zou wrote:
 Hi Dan,

 I have tried the second option. I modified the codes as you suggested.
 It works but the attachment data are still embeded in the cached
 stream. So the performance of the transformation is terrible. The code
 looks like below, could you please help to find if there is something
 wrong and how can I fix it? Thank you very much!

Try moving the interceptors inside the bounds of the 
AttachmentOutInterceptors:

First interceptor:
addAfter(AttachmentOutInterceptor.class.getName());

Second interceptor:
addBefore(AttachmentOutInterceptor.AttachmentOutEndingInterceptor.class.getName());

That should do the trick and only give you the root part.


Dan





 public class StreamInterceptor extends AbstractPhaseInterceptor {

   private StreamEndingInterceptor ending = new
 StreamEndingInterceptor(); public static final String ORIGINAL_OUTPUT
 = original_output;

 public StreamInterceptor() {
 super(Phase.PRE_STREAM);
 addBefore(AttachmentOutInterceptor.class.getName());
 }

 public void handleMessage(Message message) {
   OutputStream os = message.getContent(OutputStream.class);
   message.put(ORIGINAL_OUTPUT, os);
   CachedStream cs = new CachedStream();
 message.setContent(OutputStream.class, cs);

 //message.getInterceptorChain().doIntercept(message);
   try {
   cs.flush();
   } catch (IOException e) {
   e.printStackTrace();
   }
 message.getInterceptorChain().add(ending);
 }

 public void handleFault(Message message) {
 }

 public class StreamEndingInterceptor extends
 AbstractPhaseInterceptor {

   public StreamEndingInterceptor() {
   super(Phase.PRE_STREAM_ENDING);

 addAfter(AttachmentOutInterceptor.AttachmentOutEndingInterceptor.class
.getName()); }

   public void handleMessage(Message message) {
   try {
   CachedOutputStream csnew = (CachedOutputStream)
 message.getContent(OutputStream.class);
   OutputStream os = (OutputStream) 
 message.get(ORIGINAL_OUTPUT);

   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\; );
 System.out.println(#FIXED# + tmpXML); }

   InputStream in = new
 ByteArrayInputStream(tmpXML.getBytes()); BufferedOutputStream bos =
 new BufferedOutputStream(os); CachedOutputStream.copyStream(in, bos,
 1024);

   csnew.close();
   in.close();
   bos.close();
   os.flush();

 //message.setContent(OutputStream.class, os);
   } catch (IOException e) {
   e.printStackTrace();
   }
   }

   }

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

 }
 }

 Yuval

 dkulp wrote:
  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_OPTIM
 IZATION, 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 

How to change the namespace position in the generate xml message (SOAP message)?

2008-03-20 Thread Yuval Zou
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
   ServerNameicmnlsdb/ServerName
  /ServerDef
  LoginData
   UserIDicmadmin/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
   ServerNameicmnlsdb/ServerName
  /ServerDef
  LoginData
   UserIDicmadmin/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.ibm.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


Re: How to change the namespace position in the generate xml message (SOAP message)?

2008-03-20 Thread Ian Roberts

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;

 [snip]

/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;

 [snip]

/CreateItemRequest

The namespace http://www.ibm.com/xmlns/db2/cm/api/1.0/schema was put in the
root element.


In XML terms the two messages are exactly the same, so it's more the 
fault of whatever is parsing the message on the server side rather than 
of the XML generator in CXF.  Nontheless...


If you're using JAXB databinding then you may be able to do what you 
want using a custom namespace prefix mapper in the data binding. 
Something like this (not tested but you get the idea):


jaxws:client ...
  jaxws:dataBinding
bean class=org.apache.cxf.jaxb.JAXBDataBinding
  property name=marshallerProperties
map
  entry key=com.sun.xml.bind.namespacePrefixMapper
bean class=my.package.NoPrefixNamespaceMapper /
  /entry
/map
  /property
/bean
  /jaxws:dataBinding
/jaxws:client

Where NoPrefixNamespaceMapper is an implementation of 
com.sun.xml.bind.marshaller.NamespacePrefixMapper whose 
getPreferredPrefix method always returns .  This should force the 
marshaller to only use prefixes when it absolutely has to.


Ian

--
Ian Roberts   | Department of Computer Science
[EMAIL PROTECTED]  | University of Sheffield, UK


Re: How to change the namespace position in the generate xml message (SOAP message)?

2008-03-20 Thread Benson Margulies
The CXF JAXB binding has a custom namespace mapper which can be told to
control the prefixes. You can override it for further control. However, I'm
very skeptical as to the idea modifying where the prefixes are defined. You
might need to just make an interceptor that rewrites the XML.

On Thu, Mar 20, 2008 at 8:20 AM, Ian Roberts [EMAIL PROTECTED]
wrote:

 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;
   [snip]
  /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;
   [snip]
  /CreateItemRequest
 
  The namespace http://www.ibm.com/xmlns/db2/cm/api/1.0/schema was put in
 the
  root element.

 In XML terms the two messages are exactly the same, so it's more the
 fault of whatever is parsing the message on the server side rather than
 of the XML generator in CXF.  Nontheless...

 If you're using JAXB databinding then you may be able to do what you
 want using a custom namespace prefix mapper in the data binding.
 Something like this (not tested but you get the idea):

 jaxws:client ...
   jaxws:dataBinding
 bean class=org.apache.cxf.jaxb.JAXBDataBinding
   property name=marshallerProperties
 map
   entry key=com.sun.xml.bind.namespacePrefixMapper
 bean class=my.package.NoPrefixNamespaceMapper /
   /entry
 /map
   /property
 /bean
   /jaxws:dataBinding
 /jaxws:client

 Where NoPrefixNamespaceMapper is an implementation of
 com.sun.xml.bind.marshaller.NamespacePrefixMapper whose
 getPreferredPrefix method always returns .  This should force the
 marshaller to only use prefixes when it absolutely has to.

 Ian

 --
 Ian Roberts   | Department of Computer Science
 [EMAIL PROTECTED]  | University of Sheffield, UK



Re: How to change the namespace position in the generate xml message (SOAP message)?

2008-03-20 Thread Daniel Kulp

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
ServerNameicmnlsdb/ServerName
   /ServerDef
   LoginData
UserIDicmadmin/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
ServerNameicmnlsdb/ServerName
   /ServerDef
   LoginData
UserIDicmadmin/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();
 

Re: How to change the namespace position in the generate xml message (SOAP message)?

2008-03-20 Thread Yuval Zou
Hi Dan,

Thanks a lot for your quick and detailed response!

I will try the options provided by you. Hope everything goes well~~ :)

Yuval



2008/3/20, Daniel Kulp [EMAIL PROTECTED]:


 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
 ServerNameicmnlsdb/ServerName
/ServerDef
LoginData
 UserIDicmadmin/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
 ServerNameicmnlsdb/ServerName
/ServerDef
LoginData
 UserIDicmadmin/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