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

30,310

Solution 1

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

Solution 2

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

Solution 3

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)
Share:
30,310

Related videos on Youtube

samy-delux
Author by

samy-delux

Updated on July 09, 2022

Comments

  • samy-delux
    samy-delux almost 2 years

    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?

  • samy-delux
    samy-delux about 13 years
    Thanks, but I was specifically interested in a solution integrated with Jersey.
  • H6.
    H6. over 12 years
    +1 for the tip. But be aware that the POJO Mapping will also return NULL values in the JSON. I prefer JAXB and work with Lists which include extra POJOs.
  • Jeremy Brooks
    Jeremy Brooks over 12 years
    This is the server side setting. To do this on the client: ClientConfig clientConfig = new DefaultClientConfig(); clientConfig.getFeatures().put(JSONConfiguration.FEATURE_P‌​OJO_MAPPING, Boolean.TRUE); Client client = Client.create(clientConfig);
  • Max Schmidt
    Max Schmidt over 12 years
    @Jan What if I need to convert Book into json and into xml (request with accepts)? If I remove XmlRootElement xml serialization doesnt work anymore
  • Russ Bateman
    Russ Bateman almost 12 years
    Wow. This would have been a great answer except that adding as suggested to web.xml, no matter whether @XmlRootElement & related annotations are removed results in: com.sun.jersey.spi.container.ContainerRequest getEntity SEVERE: A message body reader for Java class com.hp.web.user.dto.ProfileDto, and Java type class com.hp.web.user.dto.ProfileDto, and MIME media type application/json; charset=UTF-8 was not found.
  • ChrisO
    ChrisO almost 10 years
    Yeah, what Russ said. This non-solution gives a "message body writer not found" error
  • emas
    emas almost 10 years
    I prefer this approach for returning complex data structure other than simple POJO. It works perfectly, it integrates with Jersey (you only have to return a "String" in your get method), and you don't have to mess up with web.xml of converters.
  • Jan
    Jan almost 6 years
    I believe my solution above from 2012 was for Jersey 1.x – maybe the answers in this thread can help with Jersey 2.x stackoverflow.com/questions/5161466/…