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
>>

Reply via email to