Wow. Thanks again!
Am 20. Januar 2015 17:46:12 MEZ, schrieb Sergey Beryozkin <[email protected]>: >There was a sync issue on the client side, CXF does sync it if a custom > >CT is set from ClientRequestFilter or WriterInterceptor but with MBW it > >was trickier; fixed, >thanks, Sergey >On 20/01/15 14:21, Sergey Beryozkin wrote: >> Supporting the registration of providers as Class types is now >supported >> on all the paths, not only via JAX-RS 2.0 Configurable. >> The CR update directly in MBW does work on the server side, but is >> broken on the client side, needs to be fixed next >> >> Sergey >> On 19/01/15 19:15, Veit Guna wrote: >>> 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 >>> >>
