user3836681
user3836681

Reputation: 55

JSON parent/root element missing from response when using Swagger Annotations

This is a Spring boot application, where as I mentioned in subject "appConfig" root element is missing from the response when I added Swagger. Any Help on this forum will be appreciated.

Here is my response object class:

@JsonRootName(value = "appConfig")
public class AppConfig {
// Using lombok for getter setters
    @Getter
    @Setter
    @JsonProperty("toggles")
    private List<Toggle> toggles;
    @Getter
    @Setter
    @JsonProperty("resources")
    private List<Resource> resources;

This is my restController

 @RequestMapping(value = "/appConfig", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE })
    @ResponseStatus(HttpStatus.OK)
    public AppConfig appConfig() {
        final AppConfig appConfig =delegate.getAppConfig();
        return appConfig;
    }

This is what I am getting in the response

//MISSING appConfig root element !!!!  
{
"resources": [
    {
      "lastUpdateTimeStamp": "string",
      "resourceName": "string"
    }
  ],
  "toggles": [
    {
      "name": "string",
      "state": true
    }
  ]
}

This is my POM dependency for Swagger:

<!-- Swagger dependencies -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.6.1</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.6.1</version>
        <scope>compile</scope>
    </dependency>

This is my Swagger Configuration class:

@Configuration
@EnableSwagger2
public class SwaggerConfig  extends WebMvcConfigurationSupport {                                    
    @Bean
    public Docket api() { 
        return new Docket(DocumentationType.SWAGGER_2)  
          .select()       
          .apis(RequestHandlerSelectors.any())
          .paths(PathSelectors.any())                          
          .build()
          .apiInfo(apiInfo());                                           
    }

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    private ApiInfo apiInfo() {
        return new ApiInfo(
          "Blah", 
          "Blah", 
          "Blah", 
          "Terms of service", 
          new Contact("Blah Administrator", "URL", "Email"), 
          "License of API", "API license URL");
   }

Upvotes: 2

Views: 2085

Answers (4)

Tony Keith
Tony Keith

Reputation: 491

I was facing the same issues using OpenApi Swagger , I've fixed it by adding a OpenApiCustomiser. To avoid duplicated answer , I posted the solution Here

Upvotes: 0

Gog1nA
Gog1nA

Reputation: 396

I got same problem, before using swagger i had response CustomResponse class with getter and setters:

public class CustomResponse<T> { 
    private T data;
    private String message;
}

and response looked liked this:

{
  "CustomResponse" : {
    "data" : {
      "prop" : "prop",
      "prop 1" : "prop1",
    },
    "message" : "true",       
  }
}

after implementing swagger result is like this:

{
    "data" : {
      "prop" : "prop",
      "prop 1" : "prop1",
    },
    "message" : "true"
  }

tried to add @JsonRootName("CustomResponse") but result is same.

here is swagger config:

@Bean
public Docket productApi() {
   return new Docket(DocumentationType.SWAGGER_2)
            .useDefaultResponseMessages(false)
            .additionalModels(typeResolver.resolve(CustomResponse.class))
            .genericModelSubstitutes(CustomResponse.class)
            .select().apis(RequestHandlerSelectors.any())
            .paths(PathSelectors.any())
            .build();

}

also tried @amseager solution:

@Bean
public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
    mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

    return mapper;
}

is there any way that to return response with root name.

Upvotes: 0

amseager
amseager

Reputation: 6391

Enable these properties at your ObjectMapper configuration:

jsonObjectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
jsonObjectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

Upvotes: 0

user3836681
user3836681

Reputation: 55

Work around which is UGLY! is define a Dummy response object and wrap your response inside it. So Swagger strips that off and gives the answer what is expected. Still looking for an answer!

Upvotes: 1

Related Questions