1. Introduction

When we use @JsonRootName in SpringBoot apps, we found that it does not work.

The maven pom.xml

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.0.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

The domain class:

@JsonRootName(value = "user")
public class MyBean {
    private int id;
    private String name;

    //getters and setters
}

The Controller:

    @RequestMapping(value="/myBean")
    public @ResponseBody
    MyBean myBean()  {
        MyBean result =  new MyBean();
        result.setId(1);
        result.setName("Jackson");
        return result;
    }

Run the code, and visit the url:

curl http://localhost:8080/myBean

What we expected:

{  
   "user":{  
      "id":1,
      "name":"Jackson"
   }
}

But we got:

{  
  "id":1,
  "name":"Jackson"
}

It seems that the @JsonRootName does not work, why did this happen?

2. Environments

  • SpringBoot 1.x and 2.x

3. The Solution

There are two ways to solve this problem.

3.1 Way 1: Use SpringBoot property

Add this line to your src/main/resources/application.properties

spring.jackson.serialization.wrap-root-value=true

Rerun the code, we get this:

{  
   "user":{  
      "id":1,
      "name":"Jackson"
   }
}

It works!

3.2 Way 2: Use SpringBoot @Configuration Bean

We can also change the jackson serialization feature by using java config class like this:

import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@Configuration
public class JacksonConfig {
    @Bean
    public Jackson2ObjectMapperBuilder jacksonBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.featuresToEnable(SerializationFeature.WRAP_ROOT_VALUE); // enables wrapping for root elements
        return builder;
    }
}

Rerun the code, we also get this:

{  
   "user":{  
      "id":1,
      "name":"Jackson"
   }
}

It works too!

4. Why did this happen?

By default, SpringBoot and Jackson object mapper disable the WRAP_ROOT_VALUE feature of serialization. So , you need to enable it explicitly by using Configuration Beans or properties.

The example source code has been uploaded to github, you can visit here to view the example source codes.