Hi
thanks for the detailed explanation of the issue you're seeing.
At the moment, using MultipartBody/Attachments explicitly makes sense in
cases when users would like to deserialize the individual parts manually,
the JAXRS providers which might be able to deal with specific parts are not
used.
If you add a WrappedString directly into a signature, instead of
MultipartBody, then it should work...
If you expect a fixed number of parts, say the root providing some info
about the (2nd) binary part, then you could have say
unpack(@Multipart("root", text/xml) MixedString str, @Multipart("2ndPart")
InputStream is) {}
Enhancing Attachement.getObject() so that a suitable provider could be found
if it's not already been done could be a good enhancement though.
cheers, Sergey
On Sun, Jul 25, 2010 at 7:25 PM, Bernhard Groll <[email protected]>wrote:
> Hello everybody,
>
> I’m very new to developing REST services with CXF and now I’ve run into
> a problem involving JAXB unmarshalling from multiparts.
>
> For test purposes I use a very simple bean for the data transfer:
>
> @XmlRootElement
> public class WrappedString {
>
> private String testString;
>
> public String getTestString() {
> return testString;
> }
>
> public void setTestString(String testString) {
> this.testString = testString;
> }
> }
>
> This is the method on the server:
>
> @POST
> @Path("test")
> @Consumes("multipart/mixed")
> @Produces("text/plain")
> public String unpackWrappedString(MultipartBody body) {
> Attachment rootAttachment = body.getRootAttachment();
> if (rootAttachment == null) {
> LOGGER.error("No root attachment found");
> }
> Object content = rootAttachment.getObject();
> if (content == null) {
>
> // This is what happens!
>
> LOGGER.error("Couldn't get an object from the root attachment");
> }
> WrappedString wrappedString = null;
> try {
> wrappedString = (WrappedString) content;
> } catch (ClassCastException e) {
> LOGGER.error("Couldn't cast to WrappedString");
> }
> return wrappedString.getTestString();
> }
>
> This is the test call:
>
> @Test
> public void testUnpackWrappedString() {
> final String testString = "Hello world";
>
> WebClient client = WebClient.create(BASE_URL);
> WrappedString wrappedString = new WrappedString();
> wrappedString.setTestString(testString);
> MultipartBody body = new MultipartBody(new Attachment("root",
> "text/xml", wrappedString));
>
> String responseString = client.path("test").type("multipart/mixed")
> .accept("text/plain").post(body, String.class);
>
> Assert.assertEquals(testString, responseString);
> }
>
> This is the HTTP message sent:
>
> POST /test-service/test HTTP/1.1
> Content-Type: multipart/mixed; type="text/xml";
> boundary="uuid:e4e3a133-4fd2-4f9a-a657-1bece83d19e1";
> start="<root>"; start-info="text/xml"
> Accept: text/plain
> User-Agent: Apache CXF 2.2.9
> Cache-Control: no-cache
> Pragma: no-cache
> Host: localhost:8084
> Connection: keep-alive
> Content-Length: 297
>
>
> --uuid:e4e3a133-4fd2-4f9a-a657-1bece83d19e1
> Content-Type: text/xml
> Content-Transfer-Encoding: binary
> Content-ID: <root>
>
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?><wrappedString>
> <testString>Hello world</testString></wrappedString>
> --uuid:e4e3a133-4fd2-4f9a-a657-1bece83d19e1--
>
> As mentioned in the server code above what happens is that the method
> getObject() returns null instead of the WrappedString object. This
> approach works fine if the attachment contains e.g. a File object (not
> using JAXB obviously). Also unmarshalling a WrappedString object works
> if it’s the sole HTTP body, i.e. not inside a multipart attachment.
>
> I would be grateful for any help in this matter.
>
> The CXF version I’m using is 2.2.9, the JDK version is 1.6.0_20, the
> service is deployed on a Tomcat 6.0.26.
>
> Best regards,
> Bernhard
>