Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java.util.Map to JSON Object with Jersey / JAXB / Jackson

I've been trying to create a Jersey REST Webservice. I want to receive and emit JSON objects from Java classes like the following:

@XmlRootElement
public class Book {

    public String code;

    public HashMap<String, String> names;

}

This should be converted into JSON like this:

{
    "code": "ABC123",
    "names": {
        "de": "Die fabelhafte Welt der Amelie",
        "fr": "Le fabuleux destin d'Amelie Poulain"
    }
}

However I can not find a standard solution for this. Everybody seems to be implementing his own wrapper solution. This requirement seems extremly basic to me; I can't believe that this is the generally accepted solution to this, especially since Jersey is really one of the more fun parts of Java.

I've also tried upgrading to Jackson 1.8 which only gives me this, which is extremly obfusicated JSON:

{
    "code": "ABC123",
    "names": {
        "entry": [{
            "key": "de",
            "value": "Die fabelhafte Welt der Amelie"
        },
        {
            "key": "fr",
            "value": "Le fabuleux destin d'Amelie Poulain"
        }]
    }
}

Are there any proposed solutions for this?

like image 593
samy-delux Avatar asked Apr 26 '11 18:04

samy-delux


3 Answers

I don't know why this isn't the default setting, and it took me a while figuring it out, but if you want working JSON conversion with Jersey, add

    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

to your web.xml and all your problems should be solved.

PS: you also need to get rid of the @XmlRootElement annotations to make it work

like image 142
Jan Avatar answered Nov 13 '22 19:11

Jan


You can use google-gson. Here is a sample code:

    @Test
    public void testGson(){
       Book book = new Book();
       book.code = "1234";
       book.names = new HashMap<String,String>();
       book.names.put("Manish", "Pandit");
       book.names.put("Some","Name");
       String json = new Gson().toJson(book);
       System.out.println(json);
   }

The output is {"code":"1234","names":{"Some":"Name","Manish":"Pandit"}}

like image 27
lobster1234 Avatar answered Nov 13 '22 18:11

lobster1234


I know it's been asked long time ago, but things changed mean time, so for the latest Jersey v2.22 that do not have anymore the package com.sun.jersey, these two dependencies added in the project pom.xml solved the same problem:

<dependency>
  <groupId>org.glassfish.jersey.media</groupId>
  <artifactId>jersey-media-json-jackson</artifactId>
  <version>2.22</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-provider</artifactId>
  <version>2.5.4</version> <!-- jackson version used by jersey v2.22 -->
</dependency>

No need to add anything in web.xml. First dependency will instruct jersey to use jackson for POJO to JSON transformations. Second dependency will register jackson as jersey JSON provider.

Also for the null problem in POJO, add this annotation to the POJO class:

@JsonInclude(JsonInclude.Include.NON_NULL)
like image 4
Lotzy Avatar answered Nov 13 '22 18:11

Lotzy