Spring Boot 启动后 Swagger 文档页面 404

问题现象

用 EasyCode 生成完代码后,Swagger 文档页面可以访问,添加了一些依赖及代码后 Swagger 文档页面 404。

问题分析

跟既存项目对比了一下,pom.xml 没什么区别,Application 类上的注解也是对的。

// 注意扫描的包名
@SpringBootApplication(scanBasePackages = {"com.ageovb.sebu"}, exclude = {DataSourceAutoConfiguration.class})
@MapperScan("com.ageovb.sebu.persistence.dao")
@EnableConfigurationProperties(MybatisPlusProperties.class)
@EnableTransactionManagement
@EnableFeignClients(basePackages = {"com.ageovb.sebu.biz.feign"})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

临时措施

如下添加 WebMvc 配置后,Swagger 可以访问:

@Configuration
public class WebMvcConfigurer extends WebMvcConfigurationSupport {

    /**
     * 发现如果继承了 WebMvcConfigurationSupport,则在 yml 中配置的相关内容会失效,如 swagger。
     *
     * @param registry 资源处理器注册器
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        // 这里使用的是 knife4j,默认是 doc.html
        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        super.addResourceHandlers(registry);
    }
}

深入分析

后来同事也帮忙一起看,看现象感觉是 WebMvc 配置的问题。

众所周知,只要引入了 spring-boot-start-web 依赖,就会自动配置 WebMvc。

最后发现是引入了一个自己封装的 EasyExcel 组件,而该组件进行了 WebMvc 配置,导致默认配置失效,其中就包括 Swagger 用到的静态资源配置。

另外,既存项目也使用到了这个 EasyExcel 组件,为啥没有问题呢?

原因是既存项目扫描的包名与 EasyExcel 组件的包名不一样,正巧 EasyExcel 组件的配置类被忽略了。

既存项目启动类:

// 注意扫描的包名
@SpringBootApplication(scanBasePackages = {"com.ageovb.secp.devicemanager"}, exclude = {DataSourceAutoConfiguration.class})
@MapperScan("com.ageovb.secp.devicemanager.persistence")
@EnableConfigurationProperties(MybatisPlusProperties.class)
@EnableFeignClients(basePackages = {"com.ageovb.secp.devicemanager.biz.feign"})
@EnableTransactionManagement
@EnableAsync
@EnableScheduling
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

Excel 组件的 WebMvc 配置类:

// 注意包名
package com.goodwe.sebu.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class WebMvcInterceptorConfig extends WebMvcConfigurationSupport {

    /**
     * 使用 Fastjson 处理返回结果
     *
     * @param converters HTTP 消息转换器
     */
    @SuppressWarnings("deprecation")
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

        super.configureMessageConverters(converters);

        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();

        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
        supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
        supportedMediaTypes.add(MediaType.APPLICATION_PDF);
        supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XML);
        supportedMediaTypes.add(MediaType.IMAGE_GIF);
        supportedMediaTypes.add(MediaType.IMAGE_JPEG);
        supportedMediaTypes.add(MediaType.IMAGE_PNG);
        supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
        supportedMediaTypes.add(MediaType.TEXT_HTML);
        supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
        supportedMediaTypes.add(MediaType.TEXT_XML);

        fastConverter.setSupportedMediaTypes(supportedMediaTypes);
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastConverter.setDateFormat("yyyy-MM-dd HH:mm:ss");
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty);
        fastConverter.setFastJsonConfig(fastJsonConfig);

        converters.add(fastConverter);
    }
}

终极方案

  1. 删除项目的 WebMvc 配置类;
  2. 删除 Excel 组件的 WebMvc 配置类并重新发布到 Maven 私服。

经验教训

公共组件不要写 WebMvc 等可能会覆盖 Spring 默认配置的配置类。

posted @ 2022-04-27 23:01  ageovb  阅读(1306)  评论(0编辑  收藏  举报