users@jersey.java.net

Re: [Jersey] Issue with Provider redirection

From: Pavel Bucek <Pavel.Bucek_at_Sun.COM>
Date: Mon, 09 Aug 2010 14:58:06 +0200

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