Return-Path: X-Original-To: apmail-cxf-users-archive@www.apache.org Delivered-To: apmail-cxf-users-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 22F7EDEF9 for ; Wed, 12 Dec 2012 10:04:23 +0000 (UTC) Received: (qmail 24555 invoked by uid 500); 12 Dec 2012 10:04:22 -0000 Delivered-To: apmail-cxf-users-archive@cxf.apache.org Received: (qmail 24495 invoked by uid 500); 12 Dec 2012 10:04:21 -0000 Mailing-List: contact users-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@cxf.apache.org Delivered-To: mailing list users@cxf.apache.org Received: (qmail 24472 invoked by uid 99); 12 Dec 2012 10:04:21 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 12 Dec 2012 10:04:21 +0000 X-ASF-Spam-Status: No, hits=-0.7 required=5.0 tests=RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of sberyozkin@gmail.com designates 209.85.217.169 as permitted sender) Received: from [209.85.217.169] (HELO mail-lb0-f169.google.com) (209.85.217.169) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 12 Dec 2012 10:04:11 +0000 Received: by mail-lb0-f169.google.com with SMTP id gk1so429248lbb.0 for ; Wed, 12 Dec 2012 02:03:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type:content-transfer-encoding; bh=2Rs3TReSz4eVFWVdV4297FoB8NeaJf/gxxQWYdiMqSA=; b=hr2KBOHJE171zGRU1Mxv611PYbx76Z5RJ29JgCNR08PVxroilt+d7lYtHvCxaOAoGh XXA9f/WNBX7PSuiumglqn83TI8KOcwqSBB0NLIJ5mtDIhGCZfELqlZDK9ECFvQ7Uc88C PJsYgKZ4VOeSt9NejUHZnJv0KnrUYecYHT0v6MaW8cNl3r4WnRsqVla8OsAhvxnOJ69q qoc+z8UnZa1u9eZHTx95f0314/DRUnJDFKtmycGVyVKh4FRGj+14AcjegA7EfHq4MG5f UMt0GgXX1nwFE3geYX/VU5W8J7aH6W1Umcjp3Ymkw5rPUlzfXY1wA3ZaGVCZE2ZryLCw o9DA== Received: by 10.112.17.170 with SMTP id p10mr201305lbd.53.1355306630735; Wed, 12 Dec 2012 02:03:50 -0800 (PST) Received: from [192.168.2.5] ([89.100.190.113]) by mx.google.com with ESMTPS id sx3sm10404203lab.9.2012.12.12.02.03.49 (version=SSLv3 cipher=OTHER); Wed, 12 Dec 2012 02:03:49 -0800 (PST) Message-ID: <50C85684.8090401@gmail.com> Date: Wed, 12 Dec 2012 10:03:48 +0000 From: Sergey Beryozkin User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120430 Thunderbird/12.0.1 MIME-Version: 1.0 To: users@cxf.apache.org Subject: Re: consuming multipart/mixed References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org Hi Stephan I've realized one more option is actually there, simply explicitly register MultipartProvider and exclude "multipart/mixed" by setting a restricted produceMediaTypes list value, say containing only multipart/related or form-data. Though the option with the custom provider is probably cleaner. Perhaps we could've made MultipartProvider optional, but I thought supporting multiparts was a pretty fundamental requirement, so it's enabled by default at the moment Cheers, Sergey On 12/12/12 07:56, Klevenz, Stephan wrote: > Jep, that sounds good and seems to be exactly what I need. > > Many Thanks! > > Greetings, > Stephan > > On 12/11/12 6:32 PM, "Sergey Beryozkin" wrote: > >> Hi Stephan >> >> On 11/12/12 16:47, Klevenz, Stephan wrote: >>> Hi Sergey, >>> >>> Thanks for already fast reply. >>> >>> I have attached a thread dump and the involved class was >>> AttachmentInInterceptor. >>> >>> I assume the MultipartBody will work and I could also access the stream >>> via injected MessageContext. The problem is that both, MultipartBody and >>> MessageContext, are CXF dependencies. Our code, at least for this part, >>> should depend on JAX-RS API only. >>> >>> So is there an option to tell CXF not to handle multipart/mixed >>> messages? >> >> Sure, can you please extend CXF MultipartProvider and override its >> readFrom and return false if it is InputStream.class ? >> Or probably better yet, register a custom JAX-RS MessageBodyReader which >> will have @Consumes("multipart/mixed"), and typed on InputStream, and >> return the input stream immediately in its readFrom. >> >> I guess with CXF 2.7.1 you can also use JAX-RS 2.0 ReaderInterceptor to >> get the same done >> >> HTH >> >> Cheers, Sergey >> >>> >>> Regards, >>> Stephan >>> >>> >>> org.apache.cxf.jaxrs.provider.MultipartProvider readFrom() >>> >>> org.apache.cxf.interceptor. AttachmentInInterceptor handleMessage() >>> >>> >>> >>> Thread [qtp14633156-18 - /odata.svc/$batch] (Suspended (breakpoint at >>> line >>> 60 in AttachmentInInterceptor)) >>> owns: PhaseInterceptorChain (id=65) >>> >>> >>> AttachmentInputInterceptor(AttachmentInInterceptor).handleMessage(Message >>> ) >>> line: 60 >>> MessageContextImpl.createAttachments(String) line: 235 >>> MessageContextImpl.get(Object) line: 73 >>> ThreadLocalMessageContext.get(Object) line: 38 >>> AttachmentUtils.getMultipartBody(MessageContext, String, >>> String, >>> String) line: 89 >>> AttachmentUtils.getAttachments(MessageContext, String, String, >>> String) line: 94 >>> MultipartProvider.readFrom(Class, Type, Annotation[], >>> MediaType, MultivaluedMap, InputStream) line: 136 >>> JAXRSUtils.readFromMessageBody(Class, Type, Annotation[], >>> InputStream, MediaType, List, Message) line: 1038 >>> JAXRSUtils.processParameter(Class, Type, Annotation[], >>> Parameter, MultivaluedMap, Message, >>> OperationResourceInfo) >>> line: 614 >>> JAXRSUtils.processParameters(OperationResourceInfo, >>> MultivaluedMap, Message) line: 578 >>> JAXRSInInterceptor.processRequest(Message) line: 238 >>> JAXRSInInterceptor.handleMessage(Message) line: 89 >>> PhaseInterceptorChain.doIntercept(Message) line: 262 >>> ChainInitiationObserver.onMessage(Message) line: 122 >>> >>> ServletDestination(AbstractHTTPDestination).invoke(ServletConfig, >>> ServletContext, HttpServletRequest, HttpServletResponse) line: 211 >>> ServletController.invokeDestination(HttpServletRequest, >>> HttpServletResponse, AbstractHTTPDestination) line: 213 >>> ServletController.invoke(HttpServletRequest, >>> HttpServletResponse) >>> line: 154 >>> >>> CXFNonSpringJaxrsServlet(CXFNonSpringServlet).invoke(HttpServletRequest, >>> HttpServletResponse) line: 129 >>> >>> >>> CXFNonSpringJaxrsServlet(AbstractHTTPServlet).handleRequest(HttpServletRe >>> qu >>> est, HttpServletResponse) line: 187 >>> >>> CXFNonSpringJaxrsServlet(AbstractHTTPServlet).doPost(HttpServletRequest, >>> HttpServletResponse) line: 110 >>> >>> CXFNonSpringJaxrsServlet(HttpServlet).service(HttpServletRequest, >>> HttpServletResponse) line: 727 >>> >>> CXFNonSpringJaxrsServlet(AbstractHTTPServlet).service(ServletRequest, >>> ServletResponse) line: 166 >>> ServletHolder.handle(Request, ServletRequest, ServletResponse) >>> line: 547 >>> ServletHandler.doHandle(String, Request, HttpServletRequest, >>> HttpServletResponse) line: 480 >>> SessionHandler.doHandle(String, Request, HttpServletRequest, >>> HttpServletResponse) line: 225 >>> ServletContextHandler(ContextHandler).doHandle(String, Request, >>> HttpServletRequest, HttpServletResponse) line: 940 >>> ServletHandler.doScope(String, Request, HttpServletRequest, >>> HttpServletResponse) line: 409 >>> SessionHandler.doScope(String, Request, HttpServletRequest, >>> HttpServletResponse) line: 186 >>> ServletContextHandler(ContextHandler).doScope(String, Request, >>> HttpServletRequest, HttpServletResponse) line: 874 >>> ServletContextHandler(ScopedHandler).handle(String, Request, >>> HttpServletRequest, HttpServletResponse) line: 117 >>> HandlerCollection.handle(String, Request, HttpServletRequest, >>> HttpServletResponse) line: 149 >>> Server(HandlerWrapper).handle(String, Request, >>> HttpServletRequest, >>> HttpServletResponse) line: 110 >>> Server.handle(HttpConnection) line: 345 >>> >>> >>> SelectChannelConnector$SelectChannelHttpConnection(HttpConnection).handle >>> Re >>> quest() line: 441 >>> HttpConnection$RequestHandler.content(Buffer) line: 936 >>> HttpParser.parseNext() line: 801 >>> HttpParser.parseAvailable() line: 224 >>> >>> >>> SelectChannelConnector$SelectChannelHttpConnection(AsyncHttpConnection).h >>> an >>> dle() line: 52 >>> SelectChannelEndPoint.handle() line: 586 >>> SelectChannelEndPoint$1.run() line: 44 >>> QueuedThreadPool.runJob(Runnable) line: 598 >>> QueuedThreadPool$3.run() line: 533 >>> Thread.run() line: not available >>> >>> >>> >>> >>> On 12/11/12 2:46 PM, "Sergey Beryozkin" wrote: >>> >>>> Stephan, by the way, I'm not seeing >>>> >>>> 'MailAttachmentInterceptor' in CXF source... >>>> >>>> Cheers, Sergey >>>> >>>> On 11/12/12 13:44, Sergey Beryozkin wrote: >>>>> Hi Stephan >>>>> >>>>> On 11/12/12 13:17, Klevenz, Stephan wrote: >>>>>> Dear CXF Gurus and Community! >>>>>> >>>>>> I want to consume a multipart/mixed payload via a stream like shown >>>>>> in >>>>>> the example code below. Unfortunately it seems that injected stream >>>>>> is >>>>>> already closed and can not be used anymore. Debugging CXF shows that >>>>>> a >>>>>> MailAttachmentInterceptor has taken the stream before it is injected. >>>>>> Is there an option to avoid that behavior? >>>>>> >>>>>> Thanks in advance. >>>>>> >>>>>> Greetings, >>>>>> Stephan >>>>>> >>>>>> >>>>>> @POST >>>>>> @Consumes("multipart/mixed") >>>>>> @Produces("multipart/mixed") >>>>>> public StreamingOutput createItem(InputStream requestBodyStream) { >>>>>> /* read the requestBodyStream like a normal input stream */ >>>>>> return new StreamingOutput() { >>>>>> >>>>>> public void write(OutputStream output) throws IOException, >>>>>> WebApplicationException { >>>>>> byte[] out = /* get some bytes to write */ >>>>>> output.write(out); >>>>>> } >>>>>> }) >>>>>> } >>>>>> >>>>>> >>>>> Can you replace the above with >>>>> >>>>> public StreamingOutput createItem(MultipartBody body) { >>>>> >>>>> // assuming a single attachment: >>>>> InputStream is = >>>>> body.getRootAttachment().getObject(InputStream.class); >>>>> //or >>>>> >>>>> InputStream is = body.getAttachmentObject("partId", >>>>> InputStream.class); >>>>> >>>>> } >>>>> >>>>> Quite a few other options are also possible, please see >>>>> >>>>> http://cxf.apache.org/docs/jax-rs-multiparts.html >>>>> >>>>> Let me know please if it works for you >>>>> HTH, Sergey >>> >