Hi Alex,
Glad you resolved this.
Jersey only looks at the type and subtype of the media type when
processing the accept header and also selecting message body readers
and writers.
If you to switch on specific media types it is recommended to do say:
application/xxxx+xml
rather than rely on media type parameters.
I am not sure from what you say if there is a bug in Jersey or not in
this respect with media type parameters. Can you clarify?
Paul.
On Feb 16, 2010, at 10:51 PM, Alex Sherwin wrote:
> I worked out a solution to this. I didn't have the @Produces
> crossed or anything, but it did have to do with using "application/
> xml". In this scenario, with JAXB annotated classes, Jersey is
> never attempting to use my custom MessageBodyWriter (isWritable is
> never even checked on my class).
>
> Instead, I'm using @Produces({ MediaType.APPLICATION_XML + ";
> type=generated"; }); on both the Resource methods and the
> MessageBodyWriter. In using the custom defined parameter, it does
> not break clients who use "Accept: application/xml", but it does
> prevent Jersey from using the wrong MessageBodyWriter... I think
> this works fine for me now
>
> jfarcand wrote:
>> Salut,
>>
>> On 10-02-16 1:19 PM, Alex Sherwin wrote:
>>> I'm using:
>>>
>>> Jersey 1.1.5
>>> Atmosphere 0.52
>>> GlassFish v2.1
>>>
>>> What I have is a set of custom objects which all implement an
>>> interface,
>>> i.e. CustomMessage. I want to create a MessageBodyWriter which
>>> always
>>> produces "application/xml" content, however, it is up to the
>>> implementation of each of these custom classes to generate the
>>> actual
>>> XML string (they can have static content, or need to be generated
>>> dynamically at writing time)
>>>
>>> The reason for this is because these messages are being broadcasted
>>> (scheduled, delayed) by Atmosphere, so the idea is that my custom
>>> MessageBodyWriter will detect if the message requires dynamically
>>> generated content, and if so it will do so before determining the
>>> size
>>> and then writing it to the output stream.
>>>
>>> This works fine, until my CustomMessage impl class has JAXB
>>> annotations
>>> on it, and it seems to (inconsistently) choose mine, or the default
>>> writer for JAXB classes.
>>>
>>> By inconsistent, I mean that i have two atmosphere services. One
>>> suspends, and one initiates a delayed broadcast. If request A
>>> suspends,
>>> and request B initiates a broadcast, the writing of B's response
>>> hits my
>>> message body writer, while the writing of A does not.
>>
>> Wild guess: what are you returning when you are using the @Suspend
>> annotation? What is the @Produces value? What's happening is if
>> nothing is returned I suspect the entity is not properly set and
>> the media type in incorrect so when the real suspend happens, the
>> entity is incorrectly set.
>>
>> Thanks
>>
>> -- Jeanfrancois
>>
>>
>>
>>>
>>> The return for B looks like this:
>>> return new Broadcastable((CustomMessage) new
>>> CustomServerTimeMessage(),
>>> topic);
>>>
>>> Now, if CustomServerTimeMessage does not use any JAXB annotations,
>>> my
>>> custom message body writer will be hit for both the response
>>> written to
>>> B and A, but with JAXB annotations, my message body writer is only
>>> hit
>>> for the response written to B.
>>>
>>> The services defined for both B and A consume "application/xml".
>>>
>>> How am I supposed to (correctly) guarantee that my
>>> MessageBodyWriter for
>>> all instances of CustomMessage will be used?
>>>
>>> My MessageBodyWriter looks like this:
>>>
>>> package com.mycompany.acmm.comet.message.writer;
>>>
>>> import com.mycompany.acmm.comet.message.CustomMessage;
>>>
>>> import java.io.IOException;
>>> import java.io.OutputStream;
>>> import java.lang.annotation.Annotation;
>>> import java.lang.reflect.Type;
>>>
>>> import javax.ws.rs.Produces;
>>> import javax.ws.rs.WebApplicationException;
>>> import javax.ws.rs.core.MediaType;
>>> import javax.ws.rs.core.MultivaluedMap;
>>> import javax.ws.rs.ext.MessageBodyWriter;
>>> import javax.ws.rs.ext.Provider;
>>>
>>> @Provider
>>> @Produces( { MediaType.APPLICATION_XML })
>>> public class CustomMessageWriter implements
>>> MessageBodyWriter<CustomMessage> {
>>>
>>> public CustomMessageWriter() {
>>>
>>> }
>>>
>>> @Override
>>> public long getSize(final CustomMessage message, Class<?> type,
>>> final
>>> Type genericType, final Annotation[] annotations, final MediaType
>>> mediaType) {
>>> if (!message.isStaticContent()) {
>>> message.generateContent();
>>> }
>>> return message.getSize();
>>> }
>>>
>>> @Override
>>> public boolean isWriteable(final Class<?> type, final Type
>>> genericType, final Annotation[] annotations, final MediaType
>>> mediaType) {
>>> return CustomMessage.class.isAssignableFrom(type);
>>> }
>>>
>>> @Override
>>> public void writeTo(final CustomMessage message, final Class<?>
>>> type,
>>> final Type genericType, final Annotation[] annotations, final
>>> MediaType
>>> mediaType,
>>> final MultivaluedMap<String, Object> httpHeaders, final
>>> OutputStream entityStream) throws IOException,
>>> WebApplicationException {
>>> entityStream.write(message.getBodyAsString().getBytes());
>>> }
>>>
>>> }
>>>
>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_atmosphere.dev.java.net
>>> For additional commands, e-mail: users-help_at_atmosphere.dev.java.net
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_atmosphere.dev.java.net
>> For additional commands, e-mail: users-help_at_atmosphere.dev.java.net
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_atmosphere.dev.java.net
> For additional commands, e-mail: users-help_at_atmosphere.dev.java.net
>