Spring Boot 2 集成 Swagger2

1 简介

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新 。接口的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。Swagger 让部署管理和使用功能强大的API从未如此简单。

2 pom文件添加Swagger2依赖

    <properties>
        <java.version>1.8</java.version>
        <swagger2.version>2.9.2</swagger2.version>
    </properties>
    
    <!--swagger2 相关依赖-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger2.version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger2.version}</version>
        </dependency>

3 创建Swagger2配置类

swagger配置类建议放在和application.java启动类在同一个包里面,这样会被自动扫描到。

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    /**
     * 初始化创建Swagger Api
     */
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                // 详细信息定制
                .apiInfo(apiInfo())
                .select()
                // 指定当前包路径
                .apis(RequestHandlerSelectors.basePackage("com.tickstep.demo"))
                // 只扫描有注解的api,用这种方式更灵活//.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                // 扫描所有 .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 添加摘要信息
     */
    private ApiInfo apiInfo() {
        // 用ApiInfoBuilder进行定制
        return new ApiInfoBuilder()
                .title("Spring boot 集成 Swagger2 API工具测试")
                .description("本接口文档是从代码自动构建而来,如果接口有更改请更新后台")
                .contact(new Contact("多啦E梦的博客", null, null))
                .version("0.0.1")
                .build();
    }
}

启动application,然后直接访问 http://localhost:8280/swagger-ui.html 即可查看swagger自动生成的api接口文档

4 更改Swagger访问路径

Swagger默认是访问路径是/swagger-ui.html,但有时候我们需要更改这个接口访问路径,以方便对后台URL接口的统一管理。
打开 springfox-swagger-ui.jar 包,我们可以看出swagger web 端UI的资源全部在这里面


springfox-swagger-ui.jar

这样思路就简单了,可以采取两种方法
1,我们可以把这个里面的资源全部拷贝到我们的resources目录,然后更改对应的路径映射即可(可能有些资源文件也需要改一下)
2,我们直接写个ModelAndView接口进行内部重定向

第2种方式侵入性低,我们选用这种
直接在SwaggerConfig.java文件增加以下代码


@Configuration
@EnableSwagger2
public class SwaggerConfig {

    // 指定文档访问URL路径
    // 例如指定以下路径,则通过这个URL访问:http://localhost:8280/actuator/swagger/swagger-ui.html
    private static final String DEFAULT_PATH = "/actuator/swagger";

    /**
     * SwaggerUI资源访问
     */
    @Bean
    public SimpleUrlHandlerMapping swaggerUrlHandlerMapping(ServletContext servletContext,
                                                            @Value("${swagger.mapping.order:10}") int order) throws Exception {
        SimpleUrlHandlerMapping urlHandlerMapping = new SimpleUrlHandlerMapping();
        Map<String, ResourceHttpRequestHandler> urlMap = new HashMap<>();

        // webjars
        PathResourceResolver pathResourceResolver = new PathResourceResolver();
        pathResourceResolver.setAllowedLocations(new ClassPathResource("META-INF/resources/webjars/"));
//            pathResourceResolver.setUrlPathHelper(new UrlPathHelper());
        ResourceHttpRequestHandler resourceHttpRequestHandler = new ResourceHttpRequestHandler();
        resourceHttpRequestHandler.setLocations(Arrays.asList(new ClassPathResource("META-INF/resources/webjars/")));
        resourceHttpRequestHandler.setResourceResolvers(Arrays.asList(pathResourceResolver));
        resourceHttpRequestHandler.setServletContext(servletContext);
        resourceHttpRequestHandler.afterPropertiesSet();
        //设置新的路径
        urlMap.put(DEFAULT_PATH + "/webjars/**", resourceHttpRequestHandler);

        // resources
        PathResourceResolver pathResourceResolverOfRes = new PathResourceResolver();
        pathResourceResolverOfRes.setAllowedLocations(new ClassPathResource("META-INF/resources/"));
//            pathResourceResolver.setUrlPathHelper(new UrlPathHelper());
        ResourceHttpRequestHandler resourceHttpRequestHandlerOfRes = new ResourceHttpRequestHandler();
        resourceHttpRequestHandlerOfRes.setLocations(Arrays.asList(new ClassPathResource("META-INF/resources/")));
        resourceHttpRequestHandlerOfRes.setResourceResolvers(Arrays.asList(pathResourceResolverOfRes));
        resourceHttpRequestHandlerOfRes.setServletContext(servletContext);
        resourceHttpRequestHandlerOfRes.afterPropertiesSet();
        //设置新的路径
        urlMap.put(DEFAULT_PATH + "/**", resourceHttpRequestHandlerOfRes);

        urlHandlerMapping.setUrlMap(urlMap);
        //调整DispatcherServlet关于SimpleUrlHandlerMapping的排序
        urlHandlerMapping.setOrder(order);
        return urlHandlerMapping;
    }

    /**
     * SwaggerUI接口访问
     */
    @Controller
    @ApiIgnore
    @RequestMapping(DEFAULT_PATH)
    public static class SwaggerResourceController implements InitializingBean {

        @Autowired
        private ApiResourceController apiResourceController;

        @Autowired
        private Environment environment;

        @Autowired
        private DocumentationCache documentationCache;

        @Autowired
        private ServiceModelToSwagger2Mapper mapper;

        @Autowired
        private JsonSerializer jsonSerializer;

        private Swagger2Controller swagger2Controller;

        @Override
        public void afterPropertiesSet() {
            swagger2Controller = new Swagger2Controller(environment, documentationCache, mapper, jsonSerializer);
        }

        /**
         * 首页
         */
        @RequestMapping
        public ModelAndView index() {
            ModelAndView modelAndView = new ModelAndView("redirect:" + DEFAULT_PATH + "/swagger-ui.html");
            return modelAndView;
        }

        @RequestMapping("/swagger-resources/configuration/security")
        @ResponseBody
        public ResponseEntity<SecurityConfiguration> securityConfiguration() {
            return apiResourceController.securityConfiguration();
        }

        @RequestMapping("/swagger-resources/configuration/ui")
        @ResponseBody
        public ResponseEntity<UiConfiguration> uiConfiguration() {
            return apiResourceController.uiConfiguration();
        }

        @RequestMapping("/swagger-resources")
        @ResponseBody
        public ResponseEntity<List<SwaggerResource>> swaggerResources() {
            return apiResourceController.swaggerResources();
        }

        @RequestMapping(value = "/v2/api-docs", method = RequestMethod.GET, produces = {"application/json", "application/hal+json"})
        @ResponseBody
        public ResponseEntity<Json> getDocumentation(
                @RequestParam(value = "group", required = false) String swaggerGroup,
                HttpServletRequest servletRequest) {
            return swagger2Controller.getDocumentation(swaggerGroup, servletRequest);
        }
    }
}

直接更改这个路径配置即可更改swagger的访问路径

private static final String DEFAULT_PATH = "/actuator/swagger";

重新运行application,然后接口访问
http://localhost:8280/actuator/swagger/swagger-ui.html

swagger ui

5 集成上传File文件接口

我们Controller上备注接口描述的时候,file比较特殊。需要按照以下规则进行备注。
dataType是"__file"类型:

 @PostMapping("/fileUpload")
    @ApiImplicitParams({@ApiImplicitParam(paramType = "form", dataType="__file", name = "file",
            value = "材料文件啊", required = false)})
    public String fileUpload(MeterialUploadForm form) {
        return form.getFile() == null ? "file is null" : form.getFile().getOriginalFilename();
    }

6 资源

代码示例请访问:https://gitlab.com/feny-blog/springboot-integrate-swagger.git

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容