Hi David I'm not exactly where the problem is but basically if (in RESTClient) I add the empty line after the boundary but just before Content-Disposition (with name=files) then it works. I suspect "\u000a" is interfering. What happens is that "Content-Disposition" of this part has 'C' stripped off and "ontent-Disposition" is saved as a header.
I'm going to try with wget, can you try independently as well ? May be using HttpClient (it works with CXF client) ? Cheers, Sergey On Thu, Jul 21, 2011 at 6:01 PM, Collard, David L (Dave) <[email protected]> wrote: > > Hi Sergey, > > No, I am not using struts. > > I made a simpler standalone example. > > //------------------------------------------------------------------------------------------------ > package tests.cxf.multi; > > import java.util.List; > > import javax.ws.rs.Consumes; > import javax.ws.rs.POST; > import javax.ws.rs.Path; > > import org.apache.cxf.jaxrs.ext.multipart.Multipart; > import org.apache.log4j.Logger; > > @Path("/tests/cxf/books") > public class MultipartBooks { > private static Logger log = Logger.getLogger(MultipartBooks.class); > > public MultipartBooks() {} > > @POST > @Path("jsonform") > @Consumes("multipart/form-data") > public void addBookJsonFromForm(Book b1) { > log.debug("MULTIPARTBOOKS: addBookJsonFromForm, Book:" + > b1.getName() + ", id:" + b1.getId()); > } > > @POST > @Path("filesform") > @Consumes("multipart/form-data") > public void addBookFilesForm( > @Multipart("owner") String name, > @Multipart("files") List<Book> books) { > log.debug("MULTIPARTBOOKS: addBookFilesForm, owner name:" + name + > ", count:" + books.size()); > for (Book book : books) { > log.debug(" Book " + book.getName()); > } > } > > } > //--------------------------------------------------------------------------------------- > > I am using firefox REST Client to send the request. > > The saved request with NO content-id: > > {"requestUrl":"http://<IP > ADDRESS>:8080/multi-1.0-SNAPSHOT/services/tests/cxf/books/filesform","requestMethod":"POST","requestBody":"--bqJky99mlBWa-ZuqjC53mG6EzbmlxB\u000aContent-Disposition: > form-data; name=\"owner\"\u000aContent-Type: > text/plain\u000a\u000aLarry\u000a--bqJky99mlBWa-ZuqjC53mG6EzbmlxB\u000aContent-Disposition: > form-data; name=\"files\"\u000aContent-Type: multipart/mixed; > boundary=_Part_4_701508.1145579811786\u000a\u000a--_Part_4_701508.1145579811786\u000aContent-Disposition: > form-data; name=\"book1\"\u000aContent-Type: application/json; > charset=US-ASCII\u000aContent-Transfer-Encoding: > 8bit\u000a\u000a{\"Book\":{\"name\":\"CXF in Action - > 1\",\"id\":123}}\u000a--_Part_4_701508.1145579811786\u000aContent-Disposition: > form-data; name=\"book2\"\u000aContent-Type: application/json; > charset=US-ASCII\u000aContent-Transfer-Encoding: > 8bit\u000a\u000a{\"Book\":{\"name\":\"CXF in Action - > 2\",\"id\":124}}\u000a--_Part_4_701508.1145579811786--\u000a--bqJky99mlBWa-ZuqjC53mG6EzbmlxB--","headers":["Content-Type","multipart/form-data; > boundary=bqJky99mlBWa-ZuqjC53mG6EzbmlxB"]} > > Resulting log: > > Jul 21, 2011 12:31:07 PM > org.apache.cxf.interceptor.AbstractLoggingInterceptor log > INFO: Inbound Message > ---------------------------- > ID: 11 > Address: http://<IP > ADDRESS>:8080/multi-1.0-SNAPSHOT/services/tests/cxf/books/filesform > Encoding: UTF-8 > Http-Method: POST > Content-Type: multipart/form-data; charset=UTF-8; > boundary=bqJky99mlBWa-ZuqjC53mG6EzbmlxB > Headers: > {Accept=[audio/x-wav,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5], > accept-charset=[ISO-8859-1,utf-8;q=0.7,*;q=0.7], accept-encoding=[gzip, > deflate], cache-control=[no-cache], connection=[keep-alive], > Content-Length=[735], content-type=[multipart/form-data; charset=UTF-8; > boundary=bqJky99mlBWa-ZuqjC53mG6EzbmlxB], > cookie=[JSESSIONID=58E6D8C6B7C8CC2812E3F19CE3CEE892], host=[<IP > ADDRESS>:8080], pragma=[no-cache], user-agent=[Mozilla/5.0 (Windows NT 5.1; > rv:5.0.1) Gecko/20100101 Firefox/5.0.1]} > Payload: --bqJky99mlBWa-ZuqjC53mG6EzbmlxB > Content-Disposition: form-data; name="owner" > Content-Type: text/plain > > Larry > --bqJky99mlBWa-ZuqjC53mG6EzbmlxB > Content-Disposition: form-data; name="files" > Content-Type: multipart/mixed; boundary=_Part_4_701508.1145579811786 > > --_Part_4_701508.1145579811786 > Content-Disposition: form-data; name="book1" > Content-Type: application/json; charset=US-ASCII > Content-Transfer-Encoding: 8bit > > {"Book":{"name":"CXF in Action - 1","id":123}} > --_Part_4_701508.1145579811786 > Content-Disposition: form-data; name="book2" > Content-Type: application/json; charset=US-ASCII > Content-Transfer-Encoding: 8bit > > {"Book":{"name":"CXF in Action - 2","id":124}} > --_Part_4_701508.1145579811786-- > --bqJky99mlBWa-ZuqjC53mG6EzbmlxB-- > -------------------------------------- > Jul 21, 2011 12:31:07 PM org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils > getMultipart > WARNING: No multipart with content id files found, request content type : > multipart/form-data;boundary=bqJky99mlBWa-ZuqjC53mG6EzbmlxB;charset=UTF-8 > Jul 21, 2011 12:31:07 PM > org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper toResponse > WARNING: WebApplicationException has been caught : no cause is available > Jul 21, 2011 12:31:07 PM > org.apache.cxf.interceptor.AbstractLoggingInterceptor log > INFO: Outbound Message > --------------------------- > ID: 11 > Response-Code: 404 > Content-Type: text/xml > Headers: {Date=[Thu, 21 Jul 2011 16:31:07 GMT]} > > > The saved request with content-id: > > {"requestUrl":"http:// <IP > ADDRESS>:8080/multi-1.0-SNAPSHOT/services/tests/cxf/books/filesform","requestMethod":"POST","requestBody":"--bqJky99mlBWa-ZuqjC53mG6EzbmlxB\u000aContent-Disposition: > form-data; name=\"owner\"\u000aContent-Type: > text/plain\u000a\u000aLarry\u000a--bqJky99mlBWa-ZuqjC53mG6EzbmlxB\u000aContent-Disposition: > form-data; name=\"files\"\u000aContent-Type: multipart/mixed; > boundary=_Part_4_701508.1145579811786\u000aContent-Id: > <files>\u000a\u000a--_Part_4_701508.1145579811786\u000aContent-Disposition: > form-data; name=\"book1\"\u000aContent-Type: application/json; > charset=US-ASCII\u000aContent-Transfer-Encoding: > 8bit\u000a\u000a{\"Book\":{\"name\":\"CXF in Action - > 1\",\"id\":123}}\u000a--_Part_4_701508.1145579811786\u000aContent-Disposition: > form-data; name=\"book2\"\u000aContent-Type: application/json; > charset=US-ASCII\u000aContent-Transfer-Encoding: > 8bit\u000a\u000a{\"Book\":{\"name\":\"CXF in Action - > 2\",\"id\":124}}\u000a--_Part_4_701508.1145579811786--\u000a--bqJky99mlBWa-ZuqjC53mG6EzbmlxB--","headers":["Content-Type","multipart/form-data; > boundary=bqJky99mlBWa-ZuqjC53mG6EzbmlxB"]} > > Resulting log: > > Jul 21, 2011 12:32:05 PM > org.apache.cxf.interceptor.AbstractLoggingInterceptor log > INFO: Inbound Message > ---------------------------- > ID: 12 > Address: http:// <IP > ADDRESS>:8080/multi-1.0-SNAPSHOT/services/tests/cxf/books/filesform > Encoding: UTF-8 > Http-Method: POST > Content-Type: multipart/form-data; charset=UTF-8; > boundary=bqJky99mlBWa-ZuqjC53mG6EzbmlxB > Headers: > {Accept=[audio/x-wav,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5], > accept-charset=[ISO-8859-1,utf-8;q=0.7,*;q=0.7], accept-encoding=[gzip, > deflate], cache-control=[no-cache], connection=[keep-alive], > Content-Length=[755], content-type=[multipart/form-data; charset=UTF-8; > boundary=bqJky99mlBWa-ZuqjC53mG6EzbmlxB], > cookie=[JSESSIONID=58E6D8C6B7C8CC2812E3F19CE3CEE892], host=[<IP > ADDRESS>:8080], pragma=[no-cache], user-agent=[Mozilla/5.0 (Windows NT 5.1; > rv:5.0.1) Gecko/20100101 Firefox/5.0.1]} > Payload: --bqJky99mlBWa-ZuqjC53mG6EzbmlxB > Content-Disposition: form-data; name="owner" > Content-Type: text/plain > > Larry > --bqJky99mlBWa-ZuqjC53mG6EzbmlxB > Content-Disposition: form-data; name="files" > Content-Type: multipart/mixed; boundary=_Part_4_701508.1145579811786 > Content-Id: <files> > > --_Part_4_701508.1145579811786 > Content-Disposition: form-data; name="book1" > Content-Type: application/json; charset=US-ASCII > Content-Transfer-Encoding: 8bit > > {"Book":{"name":"CXF in Action - 1","id":123}} > --_Part_4_701508.1145579811786 > Content-Disposition: form-data; name="book2" > Content-Type: application/json; charset=US-ASCII > Content-Transfer-Encoding: 8bit > > {"Book":{"name":"CXF in Action - 2","id":124}} > --_Part_4_701508.1145579811786-- > --bqJky99mlBWa-ZuqjC53mG6EzbmlxB-- > -------------------------------------- > DEBUG MultipartBooks [31] - MULTIPARTBOOKS: addBookFilesForm, > owner name:Larry > , count:2 > DEBUG MultipartBooks [33] - Book CXF in Action - 1 > DEBUG MultipartBooks [33] - Book CXF in Action - 2 > Jul 21, 2011 12:32:05 PM > org.apache.cxf.interceptor.AbstractLoggingInterceptor log > INFO: Outbound Message > --------------------------- > ID: 12 > Response-Code: 204 > Content-Type: text/xml > Headers: {Date=[Thu, 21 Jul 2011 16:32:05 GMT]} > > I am using tomcat 7.0.14, CXF 2.4.1, linux red hat Enterprise Server5.5. > > If you like, I can send you a war file, or eclipse project. File sharing > sites > are blocked from here or I would put it to dropbox or similar. > > Thanks! > > -- Dave Collard > > > > -----Original Message----- > From: Sergey Beryozkin [mailto:[email protected]] > Sent: Wednesday, July 20, 2011 7:41 PM > To: [email protected] > Subject: Re: JAXRS Multipart Form-Data requiring Content-ID > > > > Hi > > > > On Wed, Jul 20, 2011 at 5:32 PM, Collard, David L (Dave) > > <[email protected]> wrote: > >> I am processing multipart form-data for file uploads using JAX-RS. > >> Using Apache CXF 2.4.1 > >> > >> > >> The example addBookFilesForm shown here is not working as-is for me: > >> http://cxf.apache.org/docs/jax-rs-multiparts.html#JAX-RSMultiparts-Uploadingfiles > >> > >> Has an example request here: > >> http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentFormJsonFiles > >> > >> The second part of the form data is a multipart/mixed list of books. > >> The relevant snippet of the above request is: > >> > >> > >> Cntent-Disposition: form-data; name="files" > >> > >> Content-Type: multipart/mixed; boundary=_Part_4_701508.1145579811786 > >> > >> This fails for me with > >> > >> WARNING: No multipart with content id files found > >> > >> If I add > >> Content-Id:<files> > >> > >> to the request, then it works fine. > >> > >> Should it not use the name if the Content-ID is not specified? > >> Is there something I can do to not require this Content-Id and use the name? >> It is not > >> in my interface spec so hope to avoid requiring it. > >> > > That is a bit strange given that I can see this test working for me, > > here is the trace: > > > > POST /bookstore/books/filesform HTTP/1.1 > > Content-Type: multipart/form-data; boundary=bqJky99mlBWa-ZuqjC53mG6EzbmlxB > > User-Agent: Jakarta Commons-HttpClient/3.1 > > Host: localhost:8081 > > Content-Length: 759 > > > > > > --bqJky99mlBWa-ZuqjC53mG6EzbmlxB > > Content-Disposition: form-data; name="owner" > > Content-Type: text/plain > > > > Larry > > --bqJky99mlBWa-ZuqjC53mG6EzbmlxB > > Content-Disposition: form-data; name="files" > > Content-Type: multipart/mixed; boundary=_Part_4_701508.1145579811786 > > > > --_Part_4_701508.1145579811786 > > Content-Disposition: form-data; name="book1" > > Content-Type: application/json; charset=US-ASCII > > Content-Transfer-Encoding: 8bit > > > > {"Book":{"name":"CXF in Action - 1","id":123}} > > --_Part_4_701508.1145579811786 > > Content-Disposition: form-data; name="book2" > > Content-Type: application/json; charset=US-ASCII > > Content-Transfer-Encoding: 8bit > > > > {"Book":{"name":"CXF in Action - 2","id":124}} > > --_Part_4_701508.1145579811786-- > > --bqJky99mlBWa-ZuqjC53mG6EzbmlxB-- > > > > and the output is OK. > > I also recall updating the code to check Content-Disposition if > > Content-Id is missing. > > > > Are you using Struts by any chance ? Here are some hints just in case: > > > > http://cxf.apache.org/docs/jax-rs-multiparts.html#JAX-RSMultiparts-NoteaboutStruts > > > >> > >> On another note, there is an error in the addBookJaxbJsonForm example, the >> request has > >> > >> Content-ID: <jaxbPart> > >> > >> But the signature specifies "bookXML" not jaxbPart. > >> > >> > > Fixed - should be propagated shortly > > > > thanks, Sergey > >> > >> Thanks! > >> > >> > >> > >> -- DC > >> > >> [email protected] > >> > >> > >> > >> > > > > > > > > -- > > Sergey Beryozkin > > > > http://sberyozkin.blogspot.com > > Talend - http://www.talend.com > -- Sergey Beryozkin http://sberyozkin.blogspot.com Talend - http://www.talend.com
