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 ?
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...
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
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 ?
Cheers, Sergey
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