Adding @Encoded annotation did not change the behaviour, replacing @FormParam with @Multipart fixed the issue with QueryDSL, but not with HttpClient. Anyway, since I know now that the service is working I will be able to fix the client myself.
Thanks for your help! Kind regards, Christian -----Ursprüngliche Nachricht----- Von: Sergey Beryozkin [mailto:[email protected]] Gesendet: Donnerstag, 10. Mai 2012 13:00 An: [email protected] Betreff: Re: JAX-RS multipart file upload On 10/05/12 11:51, Sergey Beryozkin wrote: > Hi > > Please see comments below... > > On 10/05/12 11:16, Christian Lipp wrote: >> Hello! >> >> I want to upload a file using multipart form data and have problems >> with URLDecoder. The service code follows: >> >> @POST >> @Path("/document") >> @Consumes(MediaType.MULTIPART_FORM_DATA) >> public Response storeTravelDocument( >> @Context UriInfo uriInfo, >> @FormParam(value = "IDNR") String idnr, >> @FormParam(value="DOCNR") String documentNr, >> @FormParam(value="ISSUE_DATE") String issueDate, @Multipart(value = >> "image", type="image/jpeg") InputStream pictureStream) {.. >> > > What happens with this declaration is that the form payload processor > assumes the last parameter being just one more *plain* > multipart/form-data parameter. I'll check what can be fixed there, you > can definitely try adding @Encoded annotation to the last parameter, but > I suspect you may get a ClassCastException - try it please. Replacing @FormParam with @Multipart should fix the issue (as an alternative to introducing MultipartBody), however the mix-up of @FormParam & @Multipart should ideally work too. will update later on on this issue Sergey > > When you have a 'mixed' multipart/form-data payload, containing simple > String name/values pairs, alongside the binary parts, it is better to > avoid using @FormParam or @Multipart annotations and only use a > MultipartBody input parameter - it will provide a type-safe access to > all the individual parts > > Cheers, Sergey > > >> I tested with three clients, for example rest-assured: >> >> given(). >> formParam("IDNR", "A000000A"). >> formParam("DOCNR", "00001"). >> formParam("ISSUE_DATE", "14.06.2010"). >> multiPart("image", new File(picturePath), "image/jpeg"). >> expect(). >> statusCode(Response.Status.CREATED.getStatusCode()). >> when(). >> post("/document"); >> >> or HttpClient: >> >> // build mulitpart entity >> MultipartEntity entity = new MultipartEntity(); >> >> entity.addPart("IDNR", new StringBody("A000000A")); >> entity.addPart("DOCID", new StringBody("00001")); >> entity.addPart("ISSUE_DATE", new StringBody("14.06.2010")); >> >> FileBody fileBody = new FileBody(new File(picturePath), "image/jpeg"); >> entity.addPart("image", fileBody); >> >> // build post request >> String uri = System.getProperty("service.url") + "/document"; >> HttpClient httpClient = new DefaultHttpClient(); >> HttpPost httpPost = new HttpPost(uri); >> httpPost.setEntity(entity); >> >> // execute request >> HttpResponse response = httpClient.execute(httpPost); >> int code = response.getStatusLine().getStatusCode(); >> >> // validate >> assert code == Response.Status.CREATED.getStatusCode(); >> >> in all cases I receive the following exception: >> >> in escape (%) pattern - For input string: "" >> at java.net.URLDecoder.decode(URLDecoder.java:192) ~[na:1.7.0_03] >> at org.apache.cxf.common.util.UrlUtils.urlDecode(UrlUtils.java:55) >> ~[cxf-api-2.6.0.jar:2.6.0] >> at org.apache.cxf.common.util.UrlUtils.urlDecode(UrlUtils.java:63) >> ~[cxf-api-2.6.0.jar:2.6.0] >> at org.apache.cxf.jaxrs.utils.HttpUtils.urlDecode(HttpUtils.java:81) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.utils.FormUtils.populateMapFromMultipart(FormUtils.java:170) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.utils.JAXRSUtils.processFormParam(JAXRSUtils.java:746) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.utils.JAXRSUtils.createHttpParameterValue(JAXRSUtils.java:667) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:625) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:578) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:238) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:89) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262) >> [cxf-api-2.6.0.jar:2.6.0] >> ... 25 common frames omitted >> 2012-05-10 12:07:54,873 [http-bio-8080-exec-5] ERROR >> org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver - Error >> occurred during error handling, give up! >> org.apache.cxf.interceptor.Fault: URLDecoder: Illegal hex characters >> in escape (%) pattern - For input string: "" >> at >> org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:75) >> ~[cxf-api-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:322) >> [cxf-api-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:122) >> [cxf-api-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:211) >> [cxf-rt-transports-http-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:213) >> [cxf-rt-transports-http-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:154) >> [cxf-rt-transports-http-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:129) >> [cxf-rt-transports-http-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:187) >> [cxf-rt-transports-http-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:110) >> [cxf-rt-transports-http-2.6.0.jar:2.6.0] >> at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) >> [servlet-api.jar:na] >> at >> org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:166) >> [cxf-rt-transports-http-2.6.0.jar:2.6.0] >> at >> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) >> [catalina.jar:7.0.27] >> at >> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) >> [catalina.jar:7.0.27] >> at >> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) >> [catalina.jar:7.0.27] >> at >> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) >> [catalina.jar:7.0.27] >> at >> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) >> [catalina.jar:7.0.27] >> at >> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) >> [catalina.jar:7.0.27] >> at >> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) >> [catalina.jar:7.0.27] >> at >> org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) >> [catalina.jar:7.0.27] >> at >> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) >> [catalina.jar:7.0.27] >> at >> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) >> [catalina.jar:7.0.27] >> at >> org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999) >> [tomcat-coyote.jar:7.0.27] >> at >> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565) >> [tomcat-coyote.jar:7.0.27] >> at >> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307) >> [tomcat-coyote.jar:7.0.27] >> at >> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) >> [na:1.7.0_03] >> at >> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) >> [na:1.7.0_03] >> at java.lang.Thread.run(Thread.java:722) [na:1.7.0_03] >> Caused by: java.lang.IllegalArgumentException: URLDecoder: Illegal hex >> characters in escape (%) pattern - For input string: "" >> at java.net.URLDecoder.decode(URLDecoder.java:192) ~[na:1.7.0_03] >> at org.apache.cxf.common.util.UrlUtils.urlDecode(UrlUtils.java:55) >> ~[cxf-api-2.6.0.jar:2.6.0] >> at org.apache.cxf.common.util.UrlUtils.urlDecode(UrlUtils.java:63) >> ~[cxf-api-2.6.0.jar:2.6.0] >> at org.apache.cxf.jaxrs.utils.HttpUtils.urlDecode(HttpUtils.java:81) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.utils.FormUtils.populateMapFromMultipart(FormUtils.java:170) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.utils.JAXRSUtils.processFormParam(JAXRSUtils.java:746) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.utils.JAXRSUtils.createHttpParameterValue(JAXRSUtils.java:667) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:625) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:578) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:238) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:89) >> ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0] >> at >> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262) >> [cxf-api-2.6.0.jar:2.6.0] >> ... 25 common frames omitted >> >> I understand that CXF tries to decode my file, but I would like to >> prevent this. The file should just be transmitted as a UTF-8 stream, >> unchanged and not decoded. Can anyone help me? >> >> > > -- Sergey Beryozkin Talend Community Coders http://coders.talend.com/ Blog: http://sberyozkin.blogspot.com
