Springboot实战——集成Swagger2

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> Springboot实战——集成Swagger2

点击上方“Java知音”,选择“置顶公众号”

技术文章第一时间送达!

作者:liuxiaopeng

链接:http://www.cnblogs.com/paddix

一、Swagger简介

在日常的工作中,我们往往需要给前端(WEB端、IOS、Android)或者第三方提供接口,这个时候我们就需要给他们提供一份详细的API说明文档。但维护一份详细的文档可不是一件简单的事情。

首先,编写一份详细的文档本身就是一件很费时费力的事情,另一方面,由于代码和文档是分离的,所以很容易导致文档和代码的不一致。这篇文章我们就来分享一种API文档维护的方式,即通过Swagger来自动生成Restuful API文档。

那什么是Swagger?我们可以直接看下官方的描述:

THE WORLD’S MOST POPULAR API TOOLING Swagger is the world’s largest framework of API developer tools for the OpenAPI Specification(OAS), enabling development across the entire API lifecycle, from design and documentation, to test and deployment.

这段话首先告诉大家Swagger是世界上最流行的API工具,并且Swagger的目的是支撑整个API生命周期的开发,包括设计、文档以及测试和部署。这篇文章中我们会用到Swagger的文档管理和测试功能。

对Swagger的作用有了基本的认识后,我们现在来看看怎么使用。

二、Swagger与Spring boot集成

第一步:引入对应jar包:

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    dependency
        groupIdio.springfox/groupId
        artifactIdspringfox-swagger2/artifactId
        version2.6.0/version
    /dependency
    dependency
        groupIdio.springfox/groupId
        artifactIdspringfox-swagger-ui/artifactId
        version2.6.0/version
    /dependency
  • 第二步,基本信息配置:

    123456789101112131415161718192021222324
    @Configuration@EnableSwagger2public class Swagger2Config {    @Bean    public Docket createRestApi() {        return new Docket(DocumentationType.SWAGGER_2)                .apiInfo(apiInfo())                .select()                .apis(RequestHandlerSelectors.basePackage("com.pandy.blog.rest"))                .paths(PathSelectors.regex("/rest/.*"))                .build();    }     private ApiInfo apiInfo() {        return new ApiInfoBuilder()                .title("Blog系统Restful API")                .description("Blog系统Restful API")                .termsOfServiceUrl("http://127.0.0.1:8080/")                .contact("liuxiaopeng")                .version("1.0")                .build();    } }

    @Configuration
    @EnableSwagger2
    public class Swagger2Config {
    @Bean
    public Docket createRestApi() {
    return new Docket(DocumentationType.SWAGGER_2)
    .apiInfo(apiInfo())
    .select()
    .apis(RequestHandlerSelectors.basePackage(“com.pandy.blog.rest”))
    .paths(PathSelectors.regex(“/rest/.*”))
    .build();
    }

    
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Blog系统Restful API")
                .description("Blog系统Restful API")
                .termsOfServiceUrl("http://127.0.0.1:8080/")
                .contact("liuxiaopeng")
                .version("1.0")
                .build();
    }
    

    }

     

    基础的配置是对整个API文档的描述以及一些全局性的配置,对所有接口起作用。这里涉及到两个注解:

    • @Configuration是表示这是一个配置类,是JDK自带的注解,前面的文章中也已做过说明。
    • @EnableSwagger2的作用是启用Swagger2相关功能。

    在这个配置类里面我么实例化了一个Docket对象,这个对象主要包括三个方面的信息:

    • 整个API的描述信息,即ApiInfo对象包括的信息,这部分信息会在页面上展示。
    • 指定生成API文档的包名。
    • 指定生成API的路径。按路径生成API可支持四种模式,这个可以参考其源码:
      123456789101112131415161718192021222324252627282930
      public class PathSelectors {    private PathSelectors() {        throw new UnsupportedOperationException();    }     public static PredicateString any() {        return Predicates.alwaysTrue();    }     public static PredicateString none() {        return Predicates.alwaysFalse();    }     public static PredicateString regex(final String pathRegex) {        return new PredicateString() {            public boolean apply(String input) {                return input.matches(pathRegex);            }        };    }     public static PredicateString ant(final String antPattern) {        return new PredicateString() {            public boolean apply(String input) {                AntPathMatcher matcher = new AntPathMatcher();                return matcher.match(antPattern, input);            }        };    }}

    public class PathSelectors {
    private PathSelectors() {
    throw new UnsupportedOperationException();
    }

    
    public static PredicateString any() {
        return Predicates.alwaysTrue();
    }
    
    public static PredicateString none() {
        return Predicates.alwaysFalse();
    }
    
    public static PredicateString regex(final String pathRegex) {
        return new PredicateString() {
            public boolean apply(String input) {
                return input.matches(pathRegex);
            }
        };
    }
    
    public static PredicateString ant(final String antPattern) {
        return new PredicateString() {
            public boolean apply(String input) {
                AntPathMatcher matcher = new AntPathMatcher();
                return matcher.match(antPattern, input);
            }
        };
    }
    

    }

     

    从源码可以看出,Swagger总共支持任何路径都生成、任何路径都不生成以及正则匹配和ant 模式匹配四种方式。大家可能比较熟悉的是前三种,最后一种ant匹配,如果不熟悉ant的话就直接忽略吧,前三种应该足够大家在日常工作中使用了。

    有了上面的配置我们就可以看到效果了,我在com.pandy.blog.rest这个包下面有一个ArticleRestController这个类,源码如下:

    12345678910111213141516171819202122232425262728293031323334353637383940414243444546
    @RestControllerpublic class ArticleRestController {     @Autowired    private ArticleService articleService;     @RequestMapping(value = "/rest/article", method = POST, produces = "application/json")    public WebResponseMapString, Object saveArticle(@RequestBody Article article) {        article.setUserId(1L);        articleService.saveArticle(article);        MapString, Object ret = new HashMap();        ret.put("id", article.getId());        WebResponseMapString, Object response = WebResponse.getSuccessResponse(ret);        return response;    }     @RequestMapping(value = "/rest/article/{id}", method = DELETE, produces = "application/json")    public WebResponse? deleteArticle(@PathVariable Long id) {        Article article = articleService.getById(id);        article.setStatus(-1);        articleService.updateArticle(article);        WebResponseObject response = WebResponse.getSuccessResponse(null);        return response;    }     @RequestMapping(value = "/rest/article/{id}", method = PUT, produces = "application/json")    public WebResponseObject updateArticle(@PathVariable Long id, @RequestBody Article article) {        article.setId(id);        articleService.updateArticle(article);        WebResponseObject response = WebResponse.getSuccessResponse(null);        return response;    }     @RequestMapping(value = "/rest/article/{id}", method = GET, produces = "application/json")    public WebResponseArticle getArticle(@PathVariable Long id) {        Article article = articleService.getById(id);        WebResponseArticle response = WebResponse.getSuccessResponse(article);        return response;    }     @RequestMapping(value = "/test/{id}", method = GET, produces = "application/json")    public WebResponse? getNoApi(){        WebResponse? response = WebResponse.getSuccessResponse(null);        return response;    }}

    @RestController
    public class ArticleRestController {

    
    @Autowired
    private ArticleService articleService;
    
    @RequestMapping(value = "/rest/article", method = POST, produces = "application/json")
    public WebResponseMapString, Object saveArticle(@RequestBody Article article) {
        article.setUserId(1L);
        articleService.saveArticle(article);
        MapString, Object ret = new HashMap();
        ret.put("id", article.getId());
        WebResponseMapString, Object response = WebResponse.getSuccessResponse(ret);
        return response;
    }
    
    @RequestMapping(value = "/rest/article/{id}", method = DELETE, produces = "application/json")
    public WebResponse? deleteArticle(@PathVariable Long id) {
        Article article = articleService.getById(id);
        article.setStatus(-1);
        articleService.updateArticle(article);
        WebResponseObject response = WebResponse.getSuccessResponse(null);
        return response;
    }
    
    @RequestMapping(value = "/rest/article/{id}", method = PUT, produces = "application/json")
    public WebResponseObject updateArticle(@PathVariable Long id, @RequestBody Article article) {
        article.setId(id);
        articleService.updateArticle(article);
        WebResponseObject response = WebResponse.getSuccessResponse(null);
        return response;
    }
    
    @RequestMapping(value = "/rest/article/{id}", method = GET, produces = "application/json")
    public WebResponseArticle getArticle(@PathVariable Long id) {
        Article article = articleService.getById(id);
        WebResponseArticle response = WebResponse.getSuccessResponse(article);
        return response;
    }
    
    @RequestMapping(value = "/test/{id}", method = GET, produces = "application/json")
    public WebResponse? getNoApi(){
        WebResponse? response = WebResponse.getSuccessResponse(null);
        return response;
    }
    

    }

    本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

    本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

    原文链接:blog.ouyangsihai.cn >> Springboot实战——集成Swagger2


     上一篇
    Spring Boot实战——拦截器与过滤器 Spring Boot实战——拦截器与过滤器
    一、拦截器与过滤器 在讲Spring boot之前,我们先了解一下过滤器和拦截器。这两者在功能方面很类似,但是在具体技术实现方面,差距还是比较大的。在分析两者的区别之前,我们先理解一下AOP的概念,AOP不是一种具体的技术,而是一种编程思想
    下一篇 
    IDEA创建多个模块Maven SpringBoot项目 IDEA创建多个模块Maven SpringBoot项目
    点击上方“Java知音”,选择“置顶公众号” 技术文章第一时间送达! 作者:willjgl 链接:https://blog.csdn.net/WillJGL/article   最近在学习springboot,先从创建项目开始,一般