That was quick :). Thanks for the feedback!
Am 20. Januar 2015 15:21:38 MEZ, schrieb Sergey Beryozkin <[email protected]>: >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 >>
