Hi Stefan,
>I've been looking at the mtom app, but it uses cxf in a completely different
>way. No spring config for instance.
I have checked mtom sample with Spring configuration as well. It works fine:
Config:
<jaxws:client id="mtomService"
serviceName="customer:TestMtomService"
endpointName="customer:TestMtomPort"
address="http://localhost:9001/mime-test"
serviceClass="org.apache.cxf.mime.TestMtomPortType">
<jaxws:properties>
<entry key="mtom-enabled" value="true"/>
</jaxws:properties>
</jaxws:client>
Schema in wsdl:
<complexType name="ByteArrayType">
<sequence>
<element name="name" type="xsd:string" />
<element name="attachinfo" type="xsd:base64Binary"/>
</sequence>
</complexType>
<element name="testByteArray" type="types:ByteArrayType" />
<element name="testByteArrayResponse" type="types:ByteArrayType" />
<complexType name="DataHandlerType">
<sequence>
<element name="name" type="xsd:string" />
<element name="attachinfo" type="xsd:base64Binary"
xmime:expectedContentTypes="application/octet-stream"/>
</sequence>
</complexType>
Code:
URL fileURL = Client.class.getResource("/me.bmp");
Holder<String> name = new Holder<String>("Sam");
Holder<DataHandler> handler = new Holder<DataHandler>();
handler.value = new DataHandler(fileURL);
System.out.println("--Sending the me.bmp image to server");
System.out.println("--Sending a name value of " + name.value);
mtomService.testDataHandler(name, handler);
InputStream mtomIn = handler.value.getInputStream();
long fileSize = 0;
for (int i = mtomIn.read(); i != -1; i = mtomIn.read()) {
fileSize++;
}
>Anyways, I've been debugging all day with only few results so far. It seems
>like at some point in the stack, the DataHandler data is not added as an
>attachment to the soap message so there >is no reason to serialize/marshal it.
>cxf is kinda complex, and I'm struggeling to see what's going on.
Actually MTOM data marshalling isn’t related to soap message attachment, but is
kind of extension of JAXB marshaller.
Calls looks like: BareOutInterceptor.writeParts() -> DataWriterImpl.write() ->
... -> JaxbEncoderDecoder.writeObject() -> … -> MTOMXmlOutput.text()
If you will not be able to find the reason of your problem, is it possible to
distil it into small test case and send me as attachment?
Regards,
Andrei.
From: Stefan Magnus Landrø [mailto:[email protected]]
Sent: Montag, 22. April 2013 16:33
To: Andrei Shakirin
Subject: Re: CXF mtom on the client
Hi again,
I've been looking at the mtom app, but it uses cxf in a completely different
way. No spring config for instance.
Anyways, I've been debugging all day with only few results so far. It seems
like at some point in the stack, the DataHandler data is not added as an
attachment to the soap message so there is no reason to serialize/marshal it.
cxf is kinda complex, and I'm struggeling to see what's going on.
Stefan
2013/4/22 Andrei Shakirin <[email protected]<mailto:[email protected]>>
Hi,
>It's kinda nasty to use ByteArrayDataSource
>(javax.mail.util.ByteArrayDataSource) since it will hold everything in memory
>on the client. Could that affect how cxf serializes >the binary data?
Alternatively you can use FileDataSource or URL here.
Regards,
Andrei.
From: Stefan Magnus Landrø
[mailto:[email protected]<mailto:[email protected]>]
Sent: Montag, 22. April 2013 11:13
To: Andrei Shakirin
Subject: Re: CXF mtom on the client
Hi Andrei,
Thanks for your swift reply.
The code where we call the service looks like this
dok.setInnhold(new DataHandler(new
ByteArrayDataSource(dokument.getInnhold(), "application/octet-stream")));
oppdatereHenvendelseWebService.opprettDokument(dok,
dokument.getDokumentForventningsId(), dokument.getBehandlingsId());
It's kinda nasty to use ByteArrayDataSource
(javax.mail.util.ByteArrayDataSource) since it will hold everything in memory
on the client. Could that affect how cxf serializes the binary data?
Debugging AttachmentOutInterceptor
public void handleMessage(Message message) {
// Make it possible to step into this process in spite of Eclipse
// by declaring the Object.
boolean mtomEnabled = AttachmentUtil.isMtomEnabled(message);
boolean writeAtts =
MessageUtils.isTrue(message.getContextualProperty(WRITE_ATTACHMENTS))
|| (message.getAttachments() != null &&
!message.getAttachments().isEmpty());
if (!mtomEnabled && !writeAtts) {
......
I see
mtomEnabled = true and writeAtts = false
I'll have a look at the example you mention to see if there is any difference.
Stefan
2013/4/22 Andrei Shakirin <[email protected]<mailto:[email protected]>>
Hi Stefan,
Didn’t find any obvious problem in you configuration.
How you fill your WSDocument.innhold DataHandler in client, based on URL or
DataSource?
I will recommend to look mtom sample from CXF contribution and try to find the
difference with your code.
Did you test it without jaxb fluent api?
I am very curious where is really the problem.
Regards,
Andrei.
From: Stefan Magnus Landrø
[mailto:[email protected]<mailto:[email protected]>]
Sent: Montag, 22. April 2013 10:09
To: Andrei Shakirin
Subject: Re: CXF mtom on the client
Hi Andrei,
We're using cxf 2.7.4
We're using the wsdl2java maven plugin with the following config:
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.7.4</version>
<executions>
<execution>
<id>wsdl-to-java</id>
<phase>generate-sources</phase>
<goals>
<goal>wsdl2java</goal>
</goals>
<configuration>
<defaultOptions>
<extraargs>
<extraarg>-xjc-Xfluent-api</extraarg>
</extraargs>
</defaultOptions>
<wsdlOptions>
<wsdlOption>
<wsdl>${wsdl.directory}/HenvendelsesBehandling.wsdl</wsdl>
<bindingFiles>
<bindingFile>${wsdl.directory}/bindings.xml</bindingFile>
</bindingFiles>
</wsdlOption>
<wsdlOption>
<wsdl>${wsdl.directory}/Oppdaterehenvendelsesbehandling.wsdl</wsdl>
<bindingFiles>
<bindingFile>${wsdl.directory}/bindings2.xml</bindingFile>
</bindingFiles>
</wsdlOption>
</wsdlOptions>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>net.java.dev.jaxb2-commons</groupId>
<artifactId>jaxb-fluent-api</artifactId>
<version>2.1.8</version>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.4</version>
</dependency>
</dependencies>
</plugin>
This generates the following service interface:
/**
* This class was generated by Apache CXF 2.7.4
* 2013-04-22T09:44:31.901+02:00
* Generated source version: 2.7.4
*
*/
@WebService(targetNamespace = "http://........../v1", name =
"OppdatereHenvendelsesBehandlingPortType")
@XmlSeeAlso({ObjectFactory.class,
tjeneste.virksomhet.henvendelse.v1.informasjon.ObjectFactory.class})
public interface OppdatereHenvendelsesBehandlingPortType {
.....
@WebResult(name = "dokumentId", targetNamespace = "")
@RequestWrapper(localName = "opprettDokument", targetNamespace =
"http://.../v1", className =
"tjeneste.virksomhet.oppdaterehenvendelsesbehandling.v1.OpprettDokument")
@WebMethod
@ResponseWrapper(localName = "opprettDokumentResponse", targetNamespace =
"http://tjeneste/virksomhet/oppdaterehenvendelsesbehandling/v1", className =
"tjeneste.virksomhet.oppdaterehenvendelsesbehandling.v1.OpprettDokumentResponse")
public java.lang.Long opprettDokument(
@WebParam(name = "dokument", targetNamespace = "")
tjeneste.virksomhet.henvendelse.v1.informasjon.WSDokument dokument,
@WebParam(name = "dokumentForventningId", targetNamespace = "")
java.lang.Long dokumentForventningId,
@WebParam(name = "behandlingsId", targetNamespace = "")
java.lang.String behandlingsId
);
}
WSDokument is the class containing the binary data:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "dokument", propOrder = {
"id",
"filnavn",
"innhold",
"opplastetDato"
})
public class WSDokument {
protected long id;
protected String filnavn;
@XmlMimeType("application/octet-stream")
protected DataHandler innhold;
@XmlElement(type = String.class)
@XmlJavaTypeAdapter(Adapter1 .class)
@XmlSchemaType(name = "dateTime")
protected DateTime opplastetDato;
......
}
We're passing in the service interface in the spring config like this:
<jaxws:client id="oppdatereHenvendelsesBehandlingService"
xmlns:henvendelse="http://service.provider.henvendelse.dialogarena.sbl/"
serviceClass="tjeneste.virksomhet.oppdaterehenvendelsesbehandling.v1.OppdatereHenvendelsesBehandlingPortType"
address="${dokumentinnsending.webservice.henvendelse.url}/oppdatere/v1"
bus="cxf">
<jaxws:properties>
<entry key="mtom-enabled" value="true"/>
</jaxws:properties>
</jaxws:client>
I'll try to do som serious debugging today to see what is going on. Any
pointers to where I should look?
Stefan
2013/4/20 Andrei Shakirin <[email protected]<mailto:[email protected]>>
Hi,
Your configuration seems to be OK.
Do you use generated client? Could you paste the client code here as well?
Which version of CXF do you use?
Regards,
Andrei.
> -----Original Message-----
> From: Stefan Magnus Landrø
> [mailto:[email protected]<mailto:[email protected]>]
> Sent: Freitag, 19. April 2013 14:44
> To: [email protected]<mailto:[email protected]>
> Subject: CXF mtom on the client
>
> Hi,
>
> We are trying to enable mtom on the client side using the following config
>
> <jaxws:client id="........">
>
> <jaxws:properties>
> <entry key="mtom-enabled" value="true"/>
> </jaxws:properties>
>
> </jaxws:client>
>
> but are seeing some unexpected results.
>
> 10 MB files get inlined in the soap message as base64 even if cxf generating a
> HTTP mulitpart request.
>
> And yes, we have enabled mtom in the wsdl:
>
> <xs:element minOccurs="0" name="content" type="xs:base64Binary"
> xmime:expectedContentTypes="application/octet-stream"/>
>
> And, responses containing large files, get split into several parts in the
> http
> response.
>
> What could be going on?
>
> Cheers
>
> Stefan
--
BEKK Open
http://open.bekk.no
TesTcl - a unit test framework for iRules
http://testcl.com
--
BEKK Open
http://open.bekk.no
TesTcl - a unit test framework for iRules
http://testcl.com
--
BEKK Open
http://open.bekk.no
TesTcl - a unit test framework for iRules
http://testcl.com