Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomee 1.5.2 JAX-RS with Jackson 1.9.12

I've been trying for ages to get Tomee 1.5.2 JAX-RS work with Jackson. I think I've tried 100 ways.
Here is my last attempt:

I added in conf/system.properties the following:

openejb.cxf.jax-rs.providers = org.codehaus.jackson.jaxrs.JacksonJsonProvider, org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider 


I added in Tomee's lib folder:

  • jackson-mapper-asl-1.9.12.jar
  • jackson-core-asl-1.9.12.jar
  • jackson-jaxrs-1.9.12.jar


I have a simple JAX-RS class in a clean NetBeans Maven web project. Mirc is a POJO with name and car.

...imports
@Path("")
public class MyJson {
@GET
@Produces(APPLICATION_JSON)
public Object myMeth() {
    return new Mirc("Peter", "BMW");
}

I keep getting "No message body writer has been found for response class myclass".
What did I miss? How can I get it to work? I've checked all posts on stackoverflow without success.
I would really appreciate some help. Thanks.

like image 850
zmirc Avatar asked Jul 05 '13 11:07

zmirc


4 Answers

I've finally figured out how to do it, thanks to Tomee's great support. So...here it is!

I'll start by explaining how this can be achieved in latest Tomee 1.6 JAX-RS version, which will soon be released as stable. It's very stable even now, by the way.

Supposing you have a Maven Java EE 6 web app project (use NetBeans to generate one), here are the steps:
1. Add Jackson dependency in pom.xml

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-jaxrs</artifactId>
  <version>1.9.13</version>
</dependency>

2. Create openejb-jar.xml in WEB-INF (the folder with web.xml) containing:

<openejb-jar xmlns="http://www.openejb.org/openejb-jar/1.1">
  <pojo-deployment class-name="jaxrs-application">
    <properties>
      cxf.jaxrs.providers = org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider
    </properties>
  </pojo-deployment>
</openejb-jar>

For more info about this config see 1 and 2
Edit from @rmannibucau: if you use a custom jaxrs Application subclass (with @ApplicationPath for instance) you'll set the qualified name of this class instead of "jaxrs-application" (which means the default application).
3. Create a JAX-RS Resource that won't work without Jackson (example: a plain List):

import java.util.Arrays;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/jackson")
public class Resource {

  @GET
  @Produces({MediaType.APPLICATION_JSON})
  public Object sayHelloJson() {
    return Arrays.asList(new String[]{"Peter", "pan", "Ihihi"});
  }
}

4. Deploy on Tomee 1.6.0 JAX-RS edition and launch the app at: http://localhost:8080/yourAppPath/jackson This guide was tested with version 1.6.0 2013.10.24 on NetBeans 7.4.

In case you want the latest Jackson, replace the previous dependency with the following:

<dependency>
  <groupId>com.fasterxml.jackson.jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-provider</artifactId>
  <version>2.2.3</version>
</dependency>

and modify openejb-jar.xml to contain:

cxf.jaxrs.providers = com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider  

Tomee 1.5.2
For this version, providers must be specified for each resource, so not at application level as in 1.6.0. More info can be found here.

like image 123
zmirc Avatar answered Nov 20 '22 21:11

zmirc


you can use this code:

...imports
@Path("")
public class MyJson {
@GET
@Produces(APPLICATION_JSON)
public String myMeth() {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.writeValueAsString(new Mirc("Peter", "BMW"));
}

is this solve your problem ?

you can use mapper.readValue() to convert String to Object

like image 39
Mark T Avatar answered Nov 20 '22 20:11

Mark T


I had to add:

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-xc</artifactId>
    <version>1.9.13</version>
</dependency>

To the pom. I got

 java.lang.ClassNotFoundException: org.codehaus.jackson.xc.JaxbAnnotationIntrospector

otherwise.

like image 1
Ron Avatar answered Nov 20 '22 21:11

Ron


I am using openejb standalone from the TomcatEE and wanted to globally use Jackson for all JSon requests.

Adding this property to the initial context at server startup did the trick. Sharing because this was tough to track down, maybe it can help someone else.

properties.setProperty("cxf.jaxrs.providers", "com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider");
like image 1
Jeremy Bunn Avatar answered Nov 20 '22 20:11

Jeremy Bunn