1

Adding springdoc to an existing Spring MVC REST API project causes problems with custom message converters. The project configures custom message converters to set the date output to a specific format and to remove fields that contain null. This is done using a @Configuration annotated class that extends WebMvcConfigurationSupport which overrides the configureMessageConverters and adds a custom converter as well as the default converters (addDefaultHttpMessageConverters).

To add springdoc (version 1.5.1) to the project I've followed the instructions here, with the minor change of registering org.springdoc.webmvc.ui.SwaggerConfig.class instead of the listed org.springdoc.ui.SwaggerConfig.class because the latter doesn't exist. This requires adding the @EnableWebMvc annotation, which in turn requires implementing WebMvcConfigurer instead of extending WebMvcConfigurationSupport. By using WebMvcConfigurer I can't add the default converters, by using only the custom converter the springdoc JSON is escaped and therefor not valid. If the @EnableWebMvc annotation isn't added the swagger-ui.html page is not available.

I want to either use @EnableWebMvc, implementing WebMvcConfigurer and using the custom converter but prevent escaping of the springdoc JSON by adding the default converters somehow or through some other way. Or I want to use the 'old' configuration, so extending WebMvcConfigurationSupport and not add the @EnableWebMvc annotation but somehow make the swagger-ui.html page reachable.

How can I achieve either of these options?

Edit 1

The configuration class has been annotated using @EnableWebMvc and implements WebMvcConfigurer, this way the swagger-ui.html page can be reached. The converters are customized using the following method:

@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
  List<MediaType> supportedMediaTypes = new ArrayList<>();
  supportedMediaTypes.add(MediaType.APPLICATION_JSON);

  for (HttpMessageConverter<?> converter : converters) {
    if (converter instanceof MappingJackson2HttpMessageConverter) {
      MappingJackson2HttpMessageConverter jsonMessageConverter = (MappingJackson2HttpMessageConverter) converter;
      ObjectMapper objectMapper = jsonMessageConverter.getObjectMapper();
      objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
      objectMapper.setTimeZone(TimeZone.getTimeZone(timeZone));
      jsonMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
      break;
    }
  }
}

This solution is based on the accepted answer here.

This way all JSON responses from the endpoints are configured not omit null fields and use the configured time zone, the springdoc JSON also isn't escaped.

I've tried configuring a MappingJackson2HttpMessageConverter bean and adding it to the list of converters however, the springdoc JSON gets escaped making it invalid.

@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
  converters.add(customJsonConverter());
  // It's possible to add a converter at a specific index, that to doesn't
  // prevent the springdoc JSON from being escaped.
  // converters.add(1, customJsonConverter());
}

Edit 2

With the changes mentioned in the first edit everything seems to work fine. Using Tomcat 7. However, the application will be deployed using Tomcat 9 and that results in a (somewhat nondescript) error.

[2020-12-15 04:41:42,964] Artifact <artifact-name>:war: Artifact is being deployed, please wait...
15-Dec-2020 16:41:51.791 INFO [RMI TCP Connection(2)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
15-Dec-2020 16:41:52.187 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.tomcat.util.modeler.BaseModelMBean.invoke Exception invoking method [manageApp]
    java.lang.IllegalStateException: Error starting child
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:720)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
        at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1727)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:288)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
        at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:456)
        at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:405)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:288)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
        at com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:468)
        at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
        at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
        at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1408)
        at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
    Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/<application-context>]]
        at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717)
        ... 43 more
    Caused by: java.lang.ExceptionInInitializerError
        at org.springframework.boot.logging.LoggingSystemFactory.lambda$fromSpringFactories$0(LoggingSystemFactory.java:44)
        at org.springframework.boot.logging.DelegatingLoggingSystemFactory.getLoggingSystem(DelegatingLoggingSystemFactory.java:41)
        at org.springframework.boot.logging.LoggingSystem.get(LoggingSystem.java:159)
        at org.springframework.boot.logging.log4j2.SpringBootConfigurationFactory.getConfiguration(SpringBootConfigurationFactory.java:60)
        at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:453)
        at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:385)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:238)
        at org.apache.logging.log4j.core.config.Configurator.initialize(Configurator.java:158)
        at org.apache.logging.log4j.web.Log4jWebInitializerImpl.initializeNonJndi(Log4jWebInitializerImpl.java:174)
        at org.apache.logging.log4j.web.Log4jWebInitializerImpl.start(Log4jWebInitializerImpl.java:112)
        at org.apache.logging.log4j.web.Log4jServletContainerInitializer.onStartup(Log4jServletContainerInitializer.java:57)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5128)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        ... 44 more
    Caused by: java.lang.NullPointerException
        at org.springframework.core.io.support.SpringFactoriesLoader.loadSpringFactories(SpringFactoriesLoader.java:126)
        at org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(SpringFactoriesLoader.java:122)
        at org.springframework.core.io.support.SpringFactoriesLoader.loadFactories(SpringFactoriesLoader.java:98)
        at org.springframework.boot.logging.LoggingSystemFactory.lambda$fromSpringFactories$0(LoggingSystemFactory.java:44)
        at org.springframework.boot.logging.DelegatingLoggingSystemFactory.getLoggingSystem(DelegatingLoggingSystemFactory.java:41)
        at org.springframework.boot.logging.LoggingSystem.get(LoggingSystem.java:159)
        at org.springframework.boot.logging.log4j2.SpringBootConfigurationFactory.getConfiguration(SpringBootConfigurationFactory.java:60)
        at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:453)
        at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:385)
        at org.apache.logging.log4j.core.config.ConfigurationFactory.getConfiguration(ConfigurationFactory.java:260)
        at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:615)
        at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:636)
        at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:231)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
        at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
        at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:121)
        at org.apache.logging.log4j.jcl.LogAdapter.getContext(LogAdapter.java:39)
        at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
        at org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(LogFactoryImpl.java:40)
        at org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(LogFactoryImpl.java:55)
        at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:685)
        at org.springframework.core.io.support.SpringFactoriesLoader.<clinit>(SpringFactoriesLoader.java:71)
        ... 57 more
15-Dec-2020 16:41:52.189 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.tomcat.util.modeler.BaseModelMBean.invoke Exception invoking method [createStandardContext]
    javax.management.RuntimeOperationsException: Exception invoking method [manageApp]
        at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:297)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
        at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:456)
        at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:405)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:288)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
        at com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:468)
        at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
        at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
        at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1408)
        at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
    Caused by: java.lang.IllegalStateException: Error starting child
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:720)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
        at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1727)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:288)
        ... 35 more
    Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/<application-context>]]
        at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717)
        ... 43 more
    Caused by: java.lang.ExceptionInInitializerError
        at org.springframework.boot.logging.LoggingSystemFactory.lambda$fromSpringFactories$0(LoggingSystemFactory.java:44)
        at org.springframework.boot.logging.DelegatingLoggingSystemFactory.getLoggingSystem(DelegatingLoggingSystemFactory.java:41)
        at org.springframework.boot.logging.LoggingSystem.get(LoggingSystem.java:159)
        at org.springframework.boot.logging.log4j2.SpringBootConfigurationFactory.getConfiguration(SpringBootConfigurationFactory.java:60)
        at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:453)
        at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:385)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:238)
        at org.apache.logging.log4j.core.config.Configurator.initialize(Configurator.java:158)
        at org.apache.logging.log4j.web.Log4jWebInitializerImpl.initializeNonJndi(Log4jWebInitializerImpl.java:174)
        at org.apache.logging.log4j.web.Log4jWebInitializerImpl.start(Log4jWebInitializerImpl.java:112)
        at org.apache.logging.log4j.web.Log4jServletContainerInitializer.onStartup(Log4jServletContainerInitializer.java:57)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5128)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        ... 44 more
    Caused by: java.lang.NullPointerException
        at org.springframework.core.io.support.SpringFactoriesLoader.loadSpringFactories(SpringFactoriesLoader.java:126)
        at org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(SpringFactoriesLoader.java:122)
        at org.springframework.core.io.support.SpringFactoriesLoader.loadFactories(SpringFactoriesLoader.java:98)
        at org.springframework.boot.logging.LoggingSystemFactory.lambda$fromSpringFactories$0(LoggingSystemFactory.java:44)
        at org.springframework.boot.logging.DelegatingLoggingSystemFactory.getLoggingSystem(DelegatingLoggingSystemFactory.java:41)
        at org.springframework.boot.logging.LoggingSystem.get(LoggingSystem.java:159)
        at org.springframework.boot.logging.log4j2.SpringBootConfigurationFactory.getConfiguration(SpringBootConfigurationFactory.java:60)
        at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:453)
        at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:385)
        at org.apache.logging.log4j.core.config.ConfigurationFactory.getConfiguration(ConfigurationFactory.java:260)
        at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:615)
        at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:636)
        at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:231)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
        at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
        at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:121)
        at org.apache.logging.log4j.jcl.LogAdapter.getContext(LogAdapter.java:39)
        at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
        at org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(LogFactoryImpl.java:40)
        at org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(LogFactoryImpl.java:55)
        at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:685)
        at org.springframework.core.io.support.SpringFactoriesLoader.<clinit>(SpringFactoriesLoader.java:71)
        ... 57 more
[2020-12-15 04:41:52,197] Artifact <artifact-name>:war: Error during artifact deployment. See server log for details.
15-Dec-2020 16:41:52.702 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/Users/dopheidp/Programs/apache-tomcat-9.0.37/webapps/manager]
15-Dec-2020 16:41:52.775 INFO [Catalina-utility-2] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
15-Dec-2020 16:41:52.794 INFO [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/Users/dopheidp/Programs/apache-tomcat-9.0.37/webapps/manager] has finished in [92] ms

The artifact name and application context have been replaced with and respectively to be on the safe side.

The exception under Tomcat 9 seems to be caused by the springdoc and/or Spring Boot dependency that has been added to the project. By downgrading springdoc from version 1.5.1 to 1.4.8 and Spring Boot from 2.4.0 to 2.3.5.RELEASE everything works fine under Tomcat 9 (and Tomcat 7).

4

1 回答 1

0

Springdoc 已使用sprindoc 网站的说明添加到 Spring MVC 项目中。这意味着添加注释并更改扩展implementation@EnableWebMvc的配置类。所以 WebMvcConfigurationSupport WebMvcConfigurer

public class WebMvcConfig extends WebMvcConfigurationSupport { ... }

变成

@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurationSupport { ... }

这些更改导致用于全局配置 JSON 响应的消息转换器中断。为了解决这个问题,删除了以前用于配置消息转换器的方法。

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
  converters.add(jsonConverter());
  addDefaultHttpMessageConverters(converters);
}

@Bean
public MappingJackson2HttpMessageConverter jsonConverter() {
  List<MediaType> supportedMediaTypes = new ArrayList<>();
  supportedMediaTypes.add(MediaType.APPLICATION_JSON);

  Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
  builder.serializationInclusion(JsonInclude.Include.NON_NULL);
  builder.timeZone(TimeZone.getTimeZone(timeZone));

  MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(builder.build());
  jsonConverter.setSupportedMediaTypes(supportedMediaTypes);
  return jsonConverter;
}

并用下面的方法代替。其他配置消息转换器的方法似乎不起作用,请参阅已尝试的配置变体的问题。

public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
  for (HttpMessageConverter<?> converter : converters) {
    if (converter instanceof MappingJackson2HttpMessageConverter) {
      MappingJackson2HttpMessageConverter jsonMessageConverter = (MappingJackson2HttpMessageConverter) converter;
      ObjectMapper objectMapper = jsonMessageConverter.getObjectMapper();
      objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
      objectMapper.setTimeZone(TimeZone.getTimeZone(timeZone));
      jsonMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
      break;
    }
  }
}

该项目目前使用 springdoc 版本1.4.8和 Spring Boot 版本2.3.5.RELEASE作为依赖项,在撰写本文时使用最新的可用版本 springdoc1.5.1和 Spring Boot 2.4.0,导致 Tomcat 9 下的异常导致项目无法启动。

于 2020-12-16T10:58:49.520 回答