Ok, wget --header="Content-Type: multipart/form-data; boundary=bqJky99mlBWa-ZuqjC53mG6EzbmlxB" --post-file=~/work/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentFormJsonFiles http://localhost:8080/multi-1.0-SNAPSHOT/services/tests/cxf/books/filesform
works fine. Dave, I'm wondering - is it RESTClient bug ? thanks, Sergey On Fri, Jul 22, 2011 at 4:49 PM, Sergey Beryozkin <[email protected]> wrote: > I guess Attachment handker expects "\r\n" and we only have "\n" which > is a perfect line sep on Unix but is not good enough on its own as a > sep between HTTP headers and such... > Wondering if it is just a copy & paste issue ? > Cheers, Sergey > > On Fri, Jul 22, 2011 at 4:30 PM, Sergey Beryozkin <[email protected]> > wrote: >> 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] >
