users@jersey.java.net

Re: [Jersey] Issue with Provider redirection

From: Guilhem <guilhem.legal_at_geomatys.fr>
Date: Mon, 09 Aug 2010 15:42:08 +0200

Hello,

Thank you, this little hack solve my problem, if i add
@Produces("application/xml,text/xml,*/*") on my provider.
however, i think that there is a bug here because @Produces("*/*")
should have the same behavior.

Guilhem Legal

On 09/08/2010 14:58, Pavel Bucek wrote:
> Hello,
>
> I took a look into this problem and.. if you declare which mime types
> your message writer produces, it works as expected:
>
> @Provider
> @Produces("application/xml,text/xml,*/*")
> public class MyProvider<T extends Apple> implements MessageBodyWriter<T>
>
> (consider this as a quick workaround, I'm still investigating about
> this..)
>
> Pavel
>
> On 8/9/10 10:47 AM, Guilhem wrote:
>> Hi paul,
>>
>> i'm using jersey 1.3, I have made a little error in my previous that
>> i realize while creating a simple test case : my problem don't happen
>> when i use a non-standard MIME Type like:
>>
>> application/vnd.ogc.xml
>>
>> This problem happen when i use application/xml or text/xml, this is
>> probably a way to search.
>>
>> so I create a simple case and reproduce the bug, here are my classes :
>>
>> _my singleton _
>>
>> package test.provider;
>>
>> import com.sun.jersey.spi.resource.Singleton;
>> import javax.ws.rs.GET;
>> import javax.ws.rs.Path;
>> import javax.ws.rs.core.Context;
>> import javax.ws.rs.core.Response;
>> import javax.ws.rs.core.UriInfo;
>> import test.model.Apple;
>>
>> @Path("sos")
>> @Singleton
>> public class MySingleton {
>>
>> @Context
>> private volatile UriInfo uriContext;
>>
>> @GET
>> public Response doGET() {
>> String outputFormat =
>> uriContext.getQueryParameters().getFirst("output");
>> if (outputFormat == null) {
>> outputFormat = "text/xml";
>> }
>> Apple a = new Apple();
>> return Response.ok(a, outputFormat).build();
>> }
>> }
>>
>>
>> _my message body writer:_
>>
>> package test.provider;
>>
>> import java.io.IOException;
>> import java.io.OutputStream;
>> import java.lang.annotation.Annotation;
>> import java.lang.reflect.Type;
>> import java.util.logging.Logger;
>> 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;
>> import javax.xml.bind.JAXBContext;
>> import javax.xml.bind.JAXBException;
>> import javax.xml.bind.Marshaller;
>> import test.model.Apple;
>>
>> @Provider
>> public class MyProvider<T extends Apple> implements
>> MessageBodyWriter<T> {
>>
>> private static final Logger LOGGER =
>> Logger.getLogger("test.provider");
>>
>>
>> @Override
>> public boolean isWriteable(Class<?> type, Type type1,
>> Annotation[] antns, MediaType mt) {
>> System.out.println("isWritable:" +
>> Apple.class.isAssignableFrom(type));
>> return Apple.class.isAssignableFrom(type);
>> }
>>
>> @Override
>> public long getSize(T t, Class<?> type, Type type1, Annotation[]
>> antns, MediaType mt) {
>> System.out.println("get size");
>> return -1;
>> }
>>
>> @Override
>> public void writeTo(T t, Class<?> type, Type type1, Annotation[]
>> antns, MediaType mt, MultivaluedMap<String, Object> mm, OutputStream
>> out) throws IOException, WebApplicationException {
>> System.out.println("write to");
>> try {
>> Marshaller m =
>> JAXBContext.newInstance(Apple.class).createMarshaller();
>> m.marshal(t, out);
>> } catch (JAXBException ex) {
>> LOGGER.severe("JAXB exception while writing the
>> capabilities File");
>> }
>> }
>>
>> }
>>
>> and a simple model object
>>
>> package test.model;
>>
>> import javax.xml.bind.annotation.XmlElement;
>> import javax.xml.bind.annotation.XmlRootElement;
>>
>> @XmlRootElement(name="Apple")
>> public class Apple {
>>
>> @XmlElement
>> public String colour;
>>
>> }
>>
>> I use the system.out to see if i enter the messageBodyWriter
>>
>> if i make a request :
>> http://localhost:8080/Test-provider/sos?output=application/xml or
>> http://localhost:8080/Test-provider/sos?output=text/xml or
>> http://localhost:8080/Test-provider/sos
>>
>> ==> nothing in the log
>>
>> if i make a request :
>> http://localhost:8080/Test-provider/sos?output=app/xml
>>
>> ==> in the log :
>> isWritable:true
>> get size
>> write to
>>
>> So the problem here i think is relative to unrecognized mime Type.
>>
>> Guilhem Legal
>>
>>
>> On 09/08/2010 08:06, Paul Sandoz wrote:
>>> Hi Guilhem,
>>>
>>> What version of Jersey are you using?
>>>
>>> It seems like when you use text/xml Jersey is processing and that
>>> results in an exception due to some JAXB error, possibly because by
>>> default Jersey will create a JAXBContext from the class and that may
>>> be lacking some additional information than if you created the
>>> JAXBContext.
>>>
>>> The code to process text/xml and application/xml goes through the
>>> same path so you should be able to override both or indeed any JAXB
>>> support supplied by Jersey if your own MessageBodyWriter
>>> implementation is registered. Would it be possible to send a simple
>>> reproducible test case?
>>>
>>> Note that you can also define your own ContextResolver<Marshaller>
>>> that can pool Marshaller instances per-thread (as they are not
>>> thread safe and reuse the existing JAXB support.
>>>
>>> Paul.
>>>
>>> On Aug 6, 2010, at 5:58 PM, Guilhem wrote:
>>>
>>>> Hello,
>>>>
>>>> I'm using jersey in a WebService to produce XML object marshalled
>>>> with JAXB.
>>>> I want to use my own JAXBContext so i create a Jersey provider to
>>>> handle the marshalling of my object.
>>>>
>>>> My problem is that when i use the MIME type aplication/xml, my
>>>> provider is well used, but when i use the MIME type text/XML
>>>> jersey generate his own marshaller and so failed to create the
>>>> JAXBContext (because it is a little hard).
>>>>
>>>>
>>>> here is my provider (simplified) :
>>>>
>>>> import**;
>>>>
>>>> @Provider
>>>> public class CapabilitiesWriter<T extends Capabilities> implements
>>>> MessageBodyWriter<T> {
>>>>
>>>> private static final MarshallerPool pool;
>>>> static {
>>>> MarshallerPool pool = // here i build a sort of marshaller
>>>> }
>>>>
>>>> @Override
>>>> public boolean isWriteable(Class<?> type, Type type1,
>>>> Annotation[] antns, MediaType mt) {
>>>> return Capabilities.class.isAssignableFrom(type);
>>>> }
>>>>
>>>> @Override
>>>> public long getSize(T t, Class<?> type, Type type1, Annotation[]
>>>> antns, MediaType mt) {
>>>> return -1;
>>>> }
>>>>
>>>> @Override
>>>> public void writeTo(T t, Class<?> type, Type type1, Annotation[]
>>>> antns, MediaType mt, MultivaluedMap<String, Object> mm,
>>>> OutputStream out) throws IOException, WebApplicationException {
>>>> Marshaller m = // here i get my marshaller;
>>>> m.marshal(t, out);
>>>> }
>>>>
>>>> }
>>>>
>>>> and in my singleton I return a Response object like this :
>>>>
>>>> @GET
>>>> public Response doGET() throws JAXBException {
>>>> String currentMIME_Type = "something"; // here i have some
>>>> process to choose the MIME type
>>>> Capabilities capa = something; // again i have
>>>> some process building the object
>>>>
>>>> return Response.ok(capa, currentMIME_Type).build();
>>>> }
>>>>
>>>>
>>>> if "currentMIME_Type"=application/xml allright everything is fine,
>>>> i enter in the method writeTo of my provider CapabilitiesWriter.
>>>>
>>>> if "currentMIME_Type"=text/xml i get a JAXB Exception at (I have 2
>>>> stack trace, don't know why) :
>>>>
>>>> at
>>>> com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:152)
>>>>
>>>> at
>>>> com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:294)
>>>>
>>>> at
>>>> com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1140)
>>>>
>>>> at
>>>> com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1053)
>>>>
>>>> at
>>>> com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1043)
>>>>
>>>> at
>>>> com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:406)
>>>>
>>>> at
>>>> com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:477)
>>>>
>>>> at
>>>> com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:662)
>>>>
>>>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
>>>> at
>>>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
>>>>
>>>> at
>>>> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
>>>>
>>>> at
>>>> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:243)
>>>>
>>>> at
>>>> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:201)
>>>>
>>>> at
>>>> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:163)
>>>>
>>>> at
>>>> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
>>>>
>>>> at
>>>> org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:556)
>>>>
>>>> at
>>>> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
>>>>
>>>> at
>>>> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:402)
>>>>
>>>> at
>>>> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:249)
>>>>
>>>> at
>>>> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:267)
>>>>
>>>> at
>>>> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:245)
>>>>
>>>> at
>>>> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:260)
>>>>
>>>> at
>>>> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>>>>
>>>> at
>>>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>>>
>>>> at java.lang.Thread.run(Thread.java:619)
>>>>
>>>>
>>>> at
>>>> com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
>>>>
>>>> at
>>>> com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:436)
>>>>
>>>> at
>>>> com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
>>>>
>>>> at
>>>> com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100)
>>>>
>>>> at
>>>> com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143)
>>>>
>>>> at
>>>> com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:110)
>>>>
>>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>> at
>>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>>>
>>>> at
>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>>>
>>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>>> at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
>>>> at javax.xml.bind.ContextFinder.find(ContextFinder.java:376)
>>>> at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
>>>> at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
>>>> at
>>>> com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.getStoredJAXBContext(AbstractJAXBProvider.java:184)
>>>>
>>>> at
>>>> com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.getJAXBContext(AbstractJAXBProvider.java:177)
>>>>
>>>> at
>>>> com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.getMarshaller(AbstractJAXBProvider.java:155)
>>>>
>>>> at
>>>> com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.getMarshaller(AbstractJAXBProvider.java:134)
>>>>
>>>> at
>>>> com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:145)
>>>>
>>>>
>>>>
>>>>
>>>> so my question is, why the MIME type change the way of using
>>>> provider? and how redirect all mime type to my provider?
>>>>
>>>> Thanks,
>>>>
>>>> Guilhem legal
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>>
>>>
>>
>