2

I'm working on a spring boot app that should have swagger-ui enabled. When accessing http://localhost:8080/swagger-ui.html there is an error popup: "Unable to infer base url ..."

Additionaly, http://localhost:8080/v2/api-docs shows: error on line 1 at column 1: Document is empty The source-code of this page is a json, but it's requested as Content-Type application/xhtml+xml;charset=UTF-8

The cause of this seems to be my custom Jackson configuration:

@Configuration
public class JacksonConfig {

@Bean
public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter() {
    return new MappingJackson2XmlHttpMessageConverter(objectMapper());
}

@Bean
public ObjectMapper objectMapper() {
    JacksonXmlModule xmlModule = new JacksonXmlModule();
    xmlModule.setDefaultUseWrapper(false);
    XmlMapper objectMapper = new XmlMapper(xmlModule);
    objectMapper
            .registerModule(new ParameterNamesModule())
            .registerModule(new Jdk8Module())
            .registerModule(new JavaTimeModule());
    objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
    objectMapper
            .configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false)
            .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);

    return objectMapper;
}
}

With the following dependency:

<dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
    </dependency>

The problem is also described here: https://github.com/springfox/springfox/issues/1835

So my question is: How do I specify the priority of the jackson message converter to get swagger-ui working?

saimonsez
  • 344
  • 3
  • 16

2 Answers2

0

I just stumbled upon the solution while re-reading my own question.

Just add this to the above JacksonConfig class (don't know if ordering is important, but it works).

@Bean
public MappingJackson2HttpMessageConverter jsonConverter() {
    MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
    ObjectMapper objectMapper = new ObjectMapper();
    jsonConverter.setObjectMapper(objectMapper);
    return jsonConverter;
}
saimonsez
  • 344
  • 3
  • 16
0

Inside the swagger code, it checks to see if an ObjectMapper exists, and if not, it creates one to use. If a bean has been created that uses either an ObjectMapper or XMLMapper, then Swagger will use this instance, and get corrupted. The way round this is to create a bean for the ObjectMapper and use the @Primary annotation, then create the XMLMapper bean you want to use.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

@Configuration
public class MessageResponseXMLMapper {


      @Bean
      @Primary
      public ObjectMapper customObjectMapper() {
            return new ObjectMapper();
      }


      @Bean(name="customXmlMapper")
      public XmlMapper customXmlMapper() {
            return new Jackson2ObjectMapperBuilder()
                    .indentOutput(true)
                    .createXmlMapper(true)
                    .propertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE)
                    .build();     }   

}

Hope this helps

  • The challenge with this solution - it assumes that the **other** use of the `ObjectMapper` is more configurable than the Swagger code. How do we solve this if both code bases just pick the "default" one from the bean registry? – ash Feb 22 '21 at 18:59