users@jersey.java.net

Re: [Jersey] Posting JSON with Content-Type application/json (jQuery)

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 01 Dec 2008 09:57:53 +0100

On Nov 29, 2008, at 1:23 PM, sarat.pediredla wrote:

>
> Ok. Sorry for all the trouble. I think I resolved the issue. It
> seems to be
> that I should have used ContextResolved instead of MessageBodyReader
> as my
> current CustomIDProvider seems to only support XML.
>
>

Correct. JAXB only supports XML. We have added support via Jersey to
layer JSON support on top of JAXB. See JSONJAXBContext [1].

Paul.

[1] https://jersey.dev.java.net/source/browse/*checkout*/jersey/tags/jersey-1.0/api/jersey/com/sun/jersey/api/json/JSONJAXBContext.html

>
> sarat.pediredla wrote:
>>
>> I just realised that the source of the exception seems to be coming
>> from a
>> CustomIDProvider that I created to map ID's to objects. I was
>> wondering if
>> there is something in the CustomIDProvider that I have not
>> considered for
>> JSON?
>>
>> <code>
>> @Provider
>> @Component
>> @Consumes({"application/xml","application/json"})
>> public class CustomIDProvider implements MessageBodyReader {
>> @Autowired
>> private CustomIDResolver customIDResolver;
>>
>> public boolean isReadable(Class<?> aClass, Type type, Annotation[]
>> annotations, MediaType mediaType) {
>> return aClass.isAnnotationPresent(XmlRootElement.class);
>> }
>>
>> public Object readFrom(Class type, Type genericType,
>> Annotation[] annotations,
>> MediaType mediaType,
>> MultivaluedMap<String, String> httpHeaders,
>> InputStream entityStream)
>> throws IOException {
>> try {
>> JAXBContext jaxb = JAXBContext.newInstance(type);
>> Unmarshaller unmarshaller = jaxb.createUnmarshaller();
>> // set our own IDResolver because we want to resolve our XML
>> IDs
>> from the database
>> unmarshaller.setProperty(IDResolver.class.getName(),
>> customIDResolver);
>> Object obj = unmarshaller.unmarshal(entityStream);
>> if (obj instanceof JAXBElement)
>> obj = ((JAXBElement<?>) obj).getValue();
>> if (!type.isInstance(obj))
>> throw new
>> WebApplicationException(HttpURLConnection.HTTP_BAD_REQUEST);
>> return obj;
>> }
>> catch (WebApplicationException e) {
>> throw e;
>> }
>> catch (Throwable e) {
>> throw new WebApplicationException(e);
>> }
>> }
>> }
>> </code>
>>
>>
>>
>>
>> sarat.pediredla wrote:
>>>
>>> I'm using Jersey 1.0 and have included in the jersey-json 1.0
>>> dependency
>>> explicitly in my pom.xml. So the jersey-json lib is in the
>>> classpath.
>>>
>>> As for the Content-Type, here is what I get from cURL (as you can
>>> see
>>> both Content-Type and Accept are set to application/json). Unless
>>> the
>>> problem is actually in the servlet or filter not liking the encoding
>>> type? As mentioned I implemented a custom @Provider that logs
>>> MediaType
>>> to the console and that confirms the servlet/filter is definitely
>>> reading
>>> it in as application/json. Is there something obvious I am missing
>>> to
>>> invoke JSON functionality?
>>>
>>>
>>> * About to connect() to localhost port 8080 (#0)
>>> * Trying 127.0.0.1... connected
>>> * Connected to localhost (127.0.0.1) port 8080 (#0)
>>> * Server auth using Basic with user 'mark.forster'
>>>> POST /api/notes HTTP/1.1
>>>> Authorization: Basic bWFyay5mb3JzdGVyOnVzZXI=
>>>> User-Agent: curl/7.19.0 (i386-apple-darwin9.5.0) libcurl/7.19.0
>>>> zlib/1.2.3
>>>> Host: localhost:8080
>>>> Content-Type: application/json
>>>> Accept: application/json
>>>> Content-Length: 23
>>>>
>>> < HTTP/1.1 200 OK
>>> < Transfer-Encoding: chunked
>>> < Server: Jetty(6.1.5)
>>> <
>>> javax.ws.rs.WebApplicationException:
>>> javax.xml.bind.UnmarshalException
>>> - with linked exception:
>>> [org.xml.sax.SAXParseException: Content is not allowed in prolog.]
>>> at
>>> com.hedgehoglab.solomon.api.model.CustomIDProvider$$M
>>> $a255b002.readFrom(CustomIDProvider.java:56)
>>> at
>>> com.hedgehoglab.solomon.api.model.CustomIDProvider$$A
>>> $a255b002.readFrom(<generated>)
>>> at
>>> com
>>> .hedgehoglab
>>> .solomon.api.model.CustomIDProvider.readFrom(<generated>)
>>> at
>>> com
>>> .sun
>>> .jersey
>>> .spi.container.ContainerRequest.getEntity(ContainerRequest.java:348)
>>> at
>>> com
>>> .sun.jersey.impl.model.method.dispatch.EntityParamDispatchProvider
>>> $EntityInjectable.getValue(EntityParamDispatchProvider.java:81)
>>> at
>>> com
>>> .sun.jersey.impl.model.method.dispatch.EntityParamDispatchProvider
>>> $EntityParamInInvoker.getParams(EntityParamDispatchProvider.java:99)
>>> at
>>> com
>>> .sun.jersey.impl.model.method.dispatch.EntityParamDispatchProvider
>>> $ResponseOutInvoker._dispatch(EntityParamDispatchProvider.java:154)
>>> at
>>> com
>>> .sun
>>> .jersey
>>> .impl
>>> .model
>>> .method
>>> .dispatch
>>> .ResourceJavaMethodDispatcher
>>> .dispatch(ResourceJavaMethodDispatcher.java:85)
>>> at
>>> com
>>> .sun
>>> .jersey.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:
>>> 123)
>>> at
>>> com
>>> .sun
>>> .jersey
>>> .impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:71)
>>> at
>>> com
>>> .sun
>>> .jersey
>>> .impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:111)
>>> at
>>> com
>>> .sun
>>> .jersey
>>> .impl
>>> .uri
>>> .rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:
>>> 63)
>>> at
>>> com
>>> .sun
>>> .jersey
>>> .impl
>>> .application
>>> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:722)
>>> at
>>> com
>>> .sun
>>> .jersey
>>> .impl
>>> .application
>>> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:692)
>>> at
>>> com
>>> .sun
>>> .jersey
>>> .spi
>>> .container.servlet.ServletContainer.service(ServletContainer.java:
>>> 344)
>>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>>> at
>>> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:
>>> 487)
>>> at
>>> org.mortbay.jetty.servlet.ServletHandler
>>> $CachedChain.doFilter(ServletHandler.java:1093)
>>> at
>>> com
>>> .opensymphony
>>> .module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:39)
>>> at
>>> org.mortbay.jetty.servlet.ServletHandler
>>> $CachedChain.doFilter(ServletHandler.java:1084)
>>> at
>>> org
>>> .mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:
>>> 360)
>>> at
>>> org
>>> .mortbay
>>> .jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
>>> at
>>> org
>>> .mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:
>>> 181)
>>> at
>>> org
>>> .mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:
>>> 712)
>>> at
>>> org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:
>>> 405)
>>> at org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:
>>> 192)
>>> at
>>> org.appfuse.webapp.filter.StaticFilter$$M
>>> $4bee2917.doFilterInternal(StaticFilter.java:104)
>>> at
>>> org.appfuse.webapp.filter.StaticFilter$$A
>>> $4bee2917.doFilterInternal(<generated>)
>>> at
>>> org.appfuse.webapp.filter.StaticFilter.doFilterInternal(<generated>)
>>> at
>>> org
>>> .springframework
>>> .web
>>> .filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
>>> at
>>> org.mortbay.jetty.servlet.ServletHandler
>>> $CachedChain.doFilter(ServletHandler.java:1084)
>>> at
>>> org
>>> .displaytag
>>> .filter
>>> .ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
>>> at
>>> org.mortbay.jetty.servlet.ServletHandler
>>> $CachedChain.doFilter(ServletHandler.java:1084)
>>> at
>>> net
>>> .sf
>>> .ehcache.constructs.web.filter.GzipFilter.doFilter(GzipFilter.java:
>>> 106)
>>> at
>>> net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:92)
>>> at
>>> org.mortbay.jetty.servlet.ServletHandler
>>> $CachedChain.doFilter(ServletHandler.java:1084)
>>> at
>>> org.appfuse.webapp.filter.LocaleFilter$$M
>>> $ec827d59.doFilterInternal(LocaleFilter.java:63)
>>> at
>>> org.appfuse.webapp.filter.LocaleFilter$$A
>>> $ec827d59.doFilterInternal(<generated>)
>>> at
>>> org.appfuse.webapp.filter.LocaleFilter.doFilterInternal(<generated>)
>>> at
>>> org
>>> .springframework
>>> .web
>>> .filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
>>> at
>>> org.mortbay.jetty.servlet.ServletHandler
>>> $CachedChain.doFilter(ServletHandler.java:1084)
>>> at
>>> org
>>> .springframework
>>> .orm
>>> .hibernate3
>>> .support
>>> .OpenSessionInViewFilter
>>> .doFilterInternal(OpenSessionInViewFilter.java:198)
>>> at
>>> org
>>> .springframework
>>> .web
>>> .filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
>>> at
>>> org.mortbay.jetty.servlet.ServletHandler
>>> $CachedChain.doFilter(ServletHandler.java:1084)
>>> at
>>> com.hedgehoglab.solomon.utils.DisableUrlSessionFilter$$M
>>> $5040f692.doFilter(DisableUrlSessionFilter.java:90)
>>> at
>>> com.hedgehoglab.solomon.utils.DisableUrlSessionFilter$$A
>>> $5040f692.doFilter(<generated>)
>>> at
>>> com
>>> .hedgehoglab
>>> .solomon.utils.DisableUrlSessionFilter.doFilter(<generated>)
>>> at
>>> org.mortbay.jetty.servlet.ServletHandler
>>> $CachedChain.doFilter(ServletHandler.java:1084)
>>>
>>>
>>>
>>>
>>> Paul Sandoz wrote:
>>>>
>>>> Hi,
>>>>
>>>> I cannot reproduce this for 1.0 or 1.0.1-SNAPSHOT using the
>>>> embedded
>>>> Grizzly server on the Mac.
>>>>
>>>> What version of Jersey are you using?
>>>>
>>>> I modified the HelloWorld sample to be:
>>>>
>>>> @Path("/helloworld")
>>>> public class HelloWorldResource {
>>>>
>>>> @GET
>>>> @Produces({"application/json", "application/xml"})
>>>> public JAXBBean getClichedMessage() {
>>>> return new JAXBBean("content");
>>>> }
>>>>
>>>> @POST
>>>> @Produces({"application/json", "application/xml"})
>>>> @Consumes({"application/json", "application/xml"})
>>>> public JAXBBean postComment(JAXBBean comment) {
>>>> return comment;
>>>> }
>>>>
>>>> with the JAXBBean:
>>>>
>>>> @XmlRootElement
>>>> public class JAXBBean {
>>>>
>>>> public String value;
>>>> public JAXBBean() {}
>>>> public JAXBBean(String str) {
>>>> value = str;
>>>> }
>>>>
>>>> public boolean equals(Object o) {
>>>> if (!(o instanceof JAXBBean))
>>>> return false;
>>>> return ((JAXBBean) o).value.equals(value);
>>>> }
>>>>
>>>> public String toString() {
>>>> return "JAXBClass: "+value;
>>>> }
>>>> }
>>>>
>>>> With the following dependency added to the pom:
>>>>
>>>> <dependency>
>>>> <groupId>com.sun.jersey</groupId>
>>>> <artifactId>jersey-json</artifactId>
>>>> <version>${project.version}</version>
>>>> </dependency>
>>>>
>>>> And the following curl commands work correctly:
>>>>
>>>> curl -v --data-binary '{"value":"content"}' -H"Content-Type:
>>>> application/json" -H"Accept: application/xml" \
>>>> http://localhost:9998/helloworld
>>>>
>>>> curl -v --data-binary '{"value":"content"}' -H"Content-Type:
>>>> application/json" -H"Accept: application/json" \
>>>> http://localhost:9998/helloworld
>>>>
>>>> The following results in an error:
>>>>
>>>> curl -v --data-binary '{"value":"content"}' -H"Content-Type:
>>>> application/xml" -H"Accept: application/json" \
>>>> http://localhost:9998/helloworld
>>>>
>>>>
>>>> I doubt it is a Jetty issue. The obvious errors might be:
>>>>
>>>> 1) The Content-Type is not set to application/json; or
>>>>
>>>> 2) the jersey-json jar is not included in the class path (if
>>>> using the
>>>> jersey-bundle.jar then json functionality is included).
>>>>
>>>> Paul.
>>>>
>>>> On Nov 29, 2008, at 10:29 AM, sarat.pediredla wrote:
>>>>
>>>>>
>>>>> Hi Naresh,
>>>>>
>>>>> I don't think this is the same issue. Sorry if I missed mentioning
>>>>> this but
>>>>> I am running on Mac OSX Leopard in Jetty 6. Also, the call is not
>>>>> being made
>>>>> from a WebResource client but actually from the browser (Firefox
>>>>> 3).
>>>>> I tried
>>>>> the same POST using cURL at the command line but I get the same
>>>>> problems.
>>>>>
>>>>> Does this mean the problem lies with Jetty? Is there a work-
>>>>> around I
>>>>> can
>>>>> implement? One thing I am confused about is that the JSON POST
>>>>> seems
>>>>> to
>>>>> invoke a SAXParser, which I thought was for XML. I also know
>>>>> that the
>>>>> "Content is NOT allowed in Prolog" is only an issue with XML
>>>>> content.
>>>>>
>>>>> I implemented a custom @Provider and logged the MediaType being
>>>>> passed in
>>>>> the POST and it correctly says application/json, so I wonder why
>>>>> Jersey
>>>>> thinks the content is XML?
>>>>>
>>>>>
>>>>> Srinivas Naresh Bhimisetty wrote:
>>>>>>
>>>>>> Hi Sarat,
>>>>>>
>>>>>> are you trying this using the HTTPServer for deployments, and in
>>>>>> the
>>>>>> Windows environment?
>>>>>> I have observed the same behavior on Windows while using
>>>>>> "application/json", it however works fine in other environments
>>>>>> like
>>>>>> Linux or Solaris.
>>>>>> This appears to be a bug with the light-weight HTTP Server on
>>>>>> Windows.
>>>>>> Please check the attached mail thread for more details.
>>>>>>
>>>>>> Thanks,
>>>>>> Naresh
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>>
>>>>>
>>>>> --
>>>>> View this message in context:
>>>>> http://n2.nabble.com/Posting-JSON-with-Content-Type-application-json-%28jQuery%29-tp1590347p1591905.html
>>>>> Sent from the Jersey mailing list archive at Nabble.com.
>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> 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
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
> --
> View this message in context: http://n2.nabble.com/Posting-JSON-with-Content-Type-application-json-%28jQuery%29-tp1590347p1592166.html
> Sent from the Jersey mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>