Paul,
if I understand correctly then everywhere where the client is not sending a
Content-Type header but JAXBElement is the body class, I must set
@Consumes("*/*")? I wonder where in JAX-RS spec that is told. I mean, this
is not intuitive. Virtually everybody would expect that a missing @Consumes
actually defaults to "consumes anything"... Why was this decision made?
Thanks
Markus
From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
Sent: Montag, 12. Januar 2009 12:56
To: dev_at_jersey.dev.java.net
Subject: Re: [Jersey][WebDAV] Different handling of lax=true
Hi Markus,
The conformance to JAX-RS requires that, by default, an XML-related media
type is declared for the Content-Type of the request entity for production
to XML-related Java types.
Fear not it is possible to override the behavior, the following will be
possible when i commit some code to the trunk:
@Produces("*/*")
@Consumes("*/*")
public class AnyXMLRootElementProvider extends XMLRootElementProvider {
public AnyXMLRootElementProvider(@Context Providers ps) { super(ps); }
}
namely you can supply your own JAXB root element provider that works with
any media type. From what i understand, i suspect you really need to provide
your own providers for the WebDAV entities. That way you will have full
control over what media types are supported and also if a request entity is
present or not.
I think the main issue here is that the use of HTTP/WebDAV is somewhat lax:
WebDAV clients and servers from different vendors have evolved over time
with their own idiosyncrasies.
Paul.
On Jan 9, 2009, at 8:46 PM, Markus KARG wrote:
Paul,
maybe I misunderstood your first sencentence, but "...you should get an
error when the request does not contain a Content-Type" makes be worry: Lots
of HTTP requests do not containt Content-Type. So will those all not work
anymore in the latest Jersey? I mean, I have lots of productive code that
relies on the fact that JAXB can be unmarshalled with missing content type!
That would break my live application! PANIC!
Regards
Markus
From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
Sent: Freitag, 9. Januar 2009 15:23
To: Markus KARG
Cc: dev_at_jersey.dev.java.net
Subject: Re: [Jersey][WebDAV]
Hi Markus,
For the latest Jersey you should get an error when the request does not
contain a Content-Type. If there is no Content-Type present then Jersey will
assume a type of "application/octet-stream". There is no message body reader
configured for JAXB types and "application/octet-stream".
As to the root cause of the problem, i am really not sure, the media type
should not make any difference. My suspicion is that it is due to different
JAXB contexts being used.
Paul.
On Jan 1, 2009, at 3:50 PM, Markus KARG wrote:
Paul,
found a small problem yesterday, so before checking in, I wanted to clarify:
In WebDAV some XML Elements can have "ANY" content, i. e. it can have
"unknown" XML Elements ("unknown" means: The programmer of the application
will provide a JAXBClass for it and add it to the JAXBContext, but the
WebDAV framework which I provide cannot know that classes, since those are
not part of WebDAV itself -- a nice "custom extensibility" feature of
WebDAV).
So I simply used "@XmlRootElement(lax = true)" which (according to
https://jaxb.dev.java.net/jaxb20-ed/api/javax/xml/bind/annotation/XmlAnyElem
ent.html#lax()) should allow that.
And it seems to work pretty well. :-)
In the WebDAV sample, I implemented the following code which actually nicely
prints a list of "unkown" JAXBElements that are correctly recognized at
runtime. (The complexity comes from the fact that I wanted to deal with
Microsoft's known "Content-Length=0-Problem".) No problem so far. :-)
@PROPPATCH
@Path("{filename}.adr")
public final void proppatch(final InputStream body, @Context final Providers
providers, @Context final HttpHeaders httpHeaders) throws IOException {
final PropertyUpdate propertyUpdate =
providers.getMessageBodyReader(PropertyUpdate.class, PropertyUpdate.class,
new Annotation[0],
MediaType.APPLICATION_XML_TYPE).readFrom(PropertyUpdate.class,
PropertyUpdate.class, new Annotation[0], MediaType.APPLICATION_XML_TYPE,
httpHeaders.getRequestHeaders(), body);
System.out.println("PATCH PROPERTIES: " + propertyUpdate);
}
But then I recognized in the WebDAV specification that the PROPPATCH command
will NEVER have an empty body but ALWAYS have exactly one <propertyupdate>
element as its sole body. So I thought I can make the sample easiert to read
and just removed the manual body reader stuff:
@PROPPATCH
@Path("{filename}.adr")
public final void proppatch(final PropertyUpdate propertyUpdate) {
System.out.println("PATCH PROPERTIES: " + propertyUpdate);
}
Now here comes the funny thing: Now "lax=true" is not working anymore -- all
the "unknown" JAXBElements are marshalled as DOM Elements instead of
JAXBElements. Strange!
Do you have an explanation what the technical difference this makes, and how
I can workaround this problem? I'd like to provide the sample code in the
most possible simple form, you know. Is that a Jersey bug? Or is it my
fault?
I already checked the Content-Type using WireShark. Content-Type is missing
actually in the request, while my explicit version provides
APPLICATION_XML_TYPE manually. Maybe this is the difference?
Thanks for you kind help! :-)
Markus
Regards
Markus