Sounds great. I appreciate your help! Cheers Veit
On 19. Januar 2015 18:15:47 MEZ, Sergey Beryozkin <[email protected]> wrote: >On 19/01/15 17:11, Sergey Beryozkin wrote: >> Hi >> On 19/01/15 14:54, Veit Guna wrote: >>> Hi. >>> >>> Am 19.01.2015 um 15:20 schrieb Sergey Beryozkin: >>>> Hi >>>> On 19/01/15 13:57, Veit Guna wrote: >>>>> Hi. >>>>> >>>>> I'm using CXF 3.0.3. >>>>> I tried to register the provider via providers list and >referencing it >>>>> in the create() method of JAXRSClientFactory: >>>>> >>>>> List<Object> providers = new ArrayList<Object>(); >>>>> // providers.add(new JacksonJaxbJsonProvider()); >>>>> // providers.add(MultiPartWriter.class); >>>>> // providers.add(MultiPartFeature.class); >>>>> // providers.add(new MultiPartFeature()); >>>>> >>>>> I tried it the JAXRS way of specifying the class, but that didn't >work. >>>> >>>> How do you mean ? Using JAX-RS 2.0 API ? >>> Yes. I thought it might be the same like JAX-RS 2.0 API using the >>> register() methods. >>> But if that's not the same, I can live with it :). >>> >> Well, proxy API is not a standard API, though I guess it would not be >ok > >Meant to say it would be OK... > >> if it accepted the provider registrations via JAX-RS 2.0 Configurable >> API, perhaps sometime in the future it can be synced >>> >>>> >>>>> After looking at the source, I tried this one and >>>>> this almost works for me: >>>>> >>>>> >>>>> >providers.add(MultiPartWriter.class.getConstructor(Providers.class)); >>>>> >>>>> When writing the MultiPart via client proxy the MultiPartWriter >gets >>>>> invoked and it does its job. >>>>> BTW: is that the correct CXF-way to register a provider that needs >Ctor >>>>> injection or does this >>>>> use an internal way? >>>> >>>> That is OK though is unusual. Having contexts injected into >providers >>>> via constructors is rare because people typically register custom >>>> providers from Spring or the code, and besides, IMHO at least, it >is >>>> much simpler to inject a context via a setter or into a field. >>>> >>>> I think if you enable a Spring based auto-discovery on the CXF >client >>>> side then it will also work with a constructor based injection. >>>> >>>> I'll update the proxy client code to recognize providers registered >as >>>> Class too, which would be consistent with JAX-RS 2.0 Client API... >>> The class comes from jersey. It seems they are using constructor >>> injection within their providers at some places. >>> It would be nice-to-have if the CXF client proxy could support >>> registering via class as well. Will it also support constructor >>> injection then as well ;)? >>> Or is spring needed for that, too? Although I'm a big fan of spring >on >>> the server side, I'm trying to avoid it on the client side to keep >it >>> minimal. >>> >> >> As I said I'll update the proxy API so that registering providers as >> Classes will work; no Spring will be needed... >> >>> >>>> >>>>> >>>>> Nevertheless I still have a problem with the rendered request. >Although >>>>> the body is correctly written, the >>>>> Content-Type header seems "broken". It just contains >"multipart/mixed" >>>>> whereas it should contain something >>>>> like "multipart/mixed; boundary='myboundary...". The effect is, >that >>>>> the >>>>> jersey server complains about the >>>>> missing start boundary - which is really missing. >>>>> >>>>> I tried the same Jersey MultiPart writer with Resteasy, and it >seems to >>>>> work fine. The correct header is sent to the jersey server >>>>> including the boundary. So there seems something different with >CXF. >>>>> >>>>> I debugged the MultiPartWriter and I can see, that the writeTo >method >>>>> sets the correct header to the headers map >>>>> (MultivaluedMap<String, Object>) passed to the writeTo method. I >guess >>>>> that CXF doesn't take these headers into >>>>> account when writing to the stream?! I don't even know, if that is >the >>>>> correct way of a MessageBodyWriter to set >>>>> request headers. But as I mentioned before, with RestEasy the >writer >>>>> works. >>>> >>>> CXF uses its own mechanism to create the boundaries. In fact I'm >not >>>> sure you need to use the 3rd party provider for it, given that a >>>> CXF-level support is very rich: >>>> >>>> http://cxf.apache.org/docs/jax-rs-multiparts.html >>>> >>> Yeah, I stumbled accross it. But the "problem" here is, that I'm >using >>> the client proxy that reflects the server API classes which contain >the >>> Jersey MultiPart in a method signature. >>> So the client proxy expects, of course, a MultiPart object and a >>> appropriate MessageBodyWriter (MultiPartWriter from jersey) to >>> registered. >>> >>> >>>> However, let me look into a possible issue here. >>>> So I'm presuming the proxy has a @Consumes("multipart/mixed"), and >>>> then a Jersey writer sets a new Content-Type with a specific >boundary, >>>> inside a writer, and it does not override the original >Content-Type, >>>> yes ? >>>> >>> Yes, @Consumes :). >>> >>> Yes. The Jersey MultiPartWriter takes the MultiPart (also Jersey's) >and >>> creates the needed boundaries for it. It sets the needed >Content-Type >>> header correctly as "multipart/mixed; boundary='.....'" on the >headers >>> map that >>> is passed to the writeTo method (API) of the MessageBodyWriter. But >it >>> seems that this header doesn't make it into the request that is send >to >>> the server. The question here is: >>> >>> a) does CXF uses the headers that were passed to the >MessageBodyWriter >>> (and are probably modified by the writer) for creating the request? >>> b) If not, is it per spec a correct way of a MessageBodyWriter to >use >>> the passed-in headers to manipulate/set the headers of the request? >>> c) If not, what is the "correct" way for a MessageBodyWriter to set >>> headers or the content-type of the request then? >>> >>> To be honest, I don't have a clue! Maybe you have :). >>> >> >> Typically Content-Type would not be set from MBW but either from a >filer >> or WriterInterceptor. However setting it from MBW must also work; I >> vaguely recall it was working fine on the server side but looks like >> there's a sync issue on the client side - will have a look into it >asap >> >> Thanks, Sergey >> >>> Thanks for the quick reply! >>> Veit >>> >>>> >>>>> >>>>> Any idea where the problem comes from? >>>>> >>>>> Regards, >>>>> Veit >>>>> >>>>> Am 18.01.2015 um 14:09 schrieb Sergey Beryozkin: >>>>>> Hi >>>>>> >>>>>> How do you register a provider ? And which CXF version is it ? I >>>>>> expect a constructor based context injection to work, in CXF >3.0.3 at >>>>>> least. >>>>>> >>>>>> Cheers, Sergey >>>>>> On 17/01/15 10:26, Veit Guna wrote: >>>>>>> Hi. >>>>>>> >>>>>>> I have a REST server API that uses Jersey for JAX-RS >implementation >>>>>>> (2.0). To upload files to the REST service, I use their >MultiPart >>>>>>> type >>>>>>> within >>>>>>> a server API method due to a (yet) missing JAX-RS >standardization. >>>>>>> >>>>>>> Since Jersey doesn't offer a proxy-based client API (yet?), I >want to >>>>>>> use the nice CXF client proxy. I've added the jersey multipart >jar to >>>>>>> the client >>>>>>> classpath as well. But when I invoke the upload method with the >>>>>>> MultiPart parameter CXF complains about the missing >MessageBodyWriter >>>>>>> handling >>>>>>> MultiPart. So that means, that CXF isn't picking up the provider >>>>>>> automatically, right? So I've learned, I can register the >provider >>>>>>> per >>>>>>> jaxrs:providers via >>>>>>> spring xml file and also via create method. >>>>>>> >>>>>>> The problem is, that the Jersey MultiPart class expects a >>>>>>> >>>>>>> >https://docs.oracle.com/javaee/6/api/javax/ws/rs/ext/Providers.html >>>>>>> >>>>>>> to be injected in the constructor. So registering the providers >>>>>>> fails, >>>>>>> because CXF can't instantiate the class correctly. >>>>>>> So my questions is: is there a way to make CXF inject the >>>>>>> Providers to >>>>>>> the constructor? And if not, is there a way >>>>>>> for me to get a reference to the Providers within the client so >I can >>>>>>> try to instantiate the MultiPart provider by myself? >>>>>>> >>>>>>> Thanks for your help! >>>>>>> Veit >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >>> >> > > >-- >Sergey Beryozkin > >Talend Community Coders >http://coders.talend.com/ > >Blog: http://sberyozkin.blogspot.com
