88. Spring Boot集成Swagger2【从零开始学Spring Boot】

 

【视频 & 交流平台】

à SpringBoot视频

http://study.163.com/course/introduction.htm?courseId=1004329008&utm_campaign=commission&utm_source=400000000155061&utm_medium=share

à SpringCloud视频

http://study.163.com/course/introduction.htm?courseId=1004638001&utm_campaign=commission&utm_source=400000000155061&utm_medium=share

à Spring Boot源码

https://gitee.com/happyangellxq520/spring-boot

à Spring Boot交流平台

http://412887952-qq-com.iteye.com/blog/2321532

 

 

本节主要从以下几个方面进行讲解:

1Swagger的产生;

2Swagger的介绍;

3)新建maven java project;

4)在pom.xml添加依赖;

5)创建Swagger2配置类;

6)编写Controller测试类;

 

       我们一起看看每个环节的具体知识。

1Swagger的产生

       我们的RESTful API需要面对多个开发人员或多个开发团队:IOS开发、Android开发或是Web开发等。为了减少与其他团队平时开发期间的频繁沟通成本,传统做法我们会创建一份RESTful API文档来记录所有接口细节,然而这样的做法有以下几个问题:

 

    由于接口众多,并且细节复杂(需要考虑不同的HTTP请求类型、HTTP头部信息、HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳。

    随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象。

       Swagger的产生就是为了解决以上这些问题。

 

2Swagger的介绍

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

       接下来我们介绍spring boot怎么集成swagger

 

3)新建maven java project;

       新建一个maven java project取名为:spring-boot-Swagger

4)在pom.xml添加依赖;

       pom.xml添加依赖,主要是springfox-swagger2springfox-swagger-ui这里使用的是2.2.2版本的的:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

 

  <groupId>com.kfit</groupId>

  <artifactId>spring-boot-Swagger</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <packaging>jar</packaging>

 

  <name>spring-boot-Swagger</name>

  <url>http://maven.apache.org</url>

 

  <properties>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

     <!-- jdk版本号,angel在这里使用1.8,大家修改为大家本地配置的jdk版本号即可 -->

    <java.version>1.8</java.version>

  </properties>

 

<!--

       spring boot 父节点依赖,

       引入这个之后相关的引入就不需要添加version配置,

       spring boot会自动选择最合适的版本进行添加。

     -->

    <parent>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-starter-parent</artifactId>

       <version>1.3.3.RELEASE</version>

    </parent>

 

 

  <dependencies>

   

    <!-- spring boot web支持:mvc,aop... -->

       <dependency>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-web</artifactId>

       </dependency>

      

         <!-- Swagger -->

        <dependency>

            <groupId>io.springfox</groupId>

            <artifactId>springfox-swagger-ui</artifactId>

            <version>2.2.2</version>

        </dependency>

 

        <dependency>

            <groupId>io.springfox</groupId>

            <artifactId>springfox-swagger2</artifactId>

            <version>2.2.2</version>

        </dependency>

 

 

 

        <dependency>

            <groupId>org.json</groupId>

            <artifactId>json</artifactId>

        </dependency>

  </dependencies>

</project>

 

5)创建Swagger2配置类;

              编写一个swagger配置类,com.kfit.config.SwaggerConfig

package com.kfit.config;

 

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.context.request.async.DeferredResult;

 

import com.google.common.base.Predicates;

 

import springfox.documentation.builders.PathSelectors;

import springfox.documentation.service.ApiInfo;

import springfox.documentation.spi.DocumentationType;

import springfox.documentation.spring.web.plugins.Docket;

import springfox.documentation.swagger2.annotations.EnableSwagger2;

 

/**

 * Swagger配置类:

 * @author Angel --守护天使

 * @version v.0.1

 * @date 201697

 */

@Configuration

@EnableSwagger2

public class SwaggerConfig {

   

    /**

     * SpringBoot默认已经将classpath:/META-INF/resources/classpath:/META-INF/resources/webjars/映射

     * 所以该方法不需要重写,如果在SpringMVC中,可能需要重写定义(我没有尝试)

     * 重写该方法需要 extends WebMvcConfigurerAdapter

     *

     */

//    @Override

//    public void addResourceHandlers(ResourceHandlerRegistry registry) {

//        registry.addResourceHandler("swagger-ui.html")

//                .addResourceLocations("classpath:/META-INF/resources/");

//

//        registry.addResourceHandler("/webjars/**")

//                .addResourceLocations("classpath:/META-INF/resources/webjars/");

//    }

   

    /**

     * 可以定义多个组,比如本类中定义把testdemo区分开了

     * (访问页面就可以看到效果了)

     *

     */

   

    @SuppressWarnings("unchecked")

    @Bean

    public Docket testApi(){

       Docket docket = new Docket(DocumentationType.SWAGGER_2)

              .groupName("test")

              .genericModelSubstitutes(DeferredResult.class)

              .useDefaultResponseMessages(false)

                .forCodeGeneration(true)

                .pathMapping("/")// base,最终调用接口后会和paths拼接在一起

                .select()

                .paths(Predicates.or(PathSelectors.regex("/api/.*")))//过滤的接口

                .build()

                .apiInfo(testApiInfo());

              ;

       return docket;

    }

   

    @SuppressWarnings("unchecked")

    @Bean

    public Docket demoApi() {

        returnnew Docket(DocumentationType.SWAGGER_2)

                .groupName("demo")

                .genericModelSubstitutes(DeferredResult.class)

//              .genericModelSubstitutes(ResponseEntity.class)

                .useDefaultResponseMessages(false)

                .forCodeGeneration(false)

                .pathMapping("/")

                .select()

                .paths(Predicates.or(PathSelectors.regex("/demo/.*")))//过滤的接口

                .build()

                .apiInfo(demoApiInfo());

    }

   

     private ApiInfo testApiInfo() {

            ApiInfo apiInfo = new ApiInfo("Test相关接口",//大标题

                    "Test相关接口,主要用于测试.",//小标题

                    "1.0",//版本

                    "http://412887952-qq-com.iteye.com/",

                    "Angel",//作者

                    "北京知远信息科技有限公司",//链接显示文字

                    "http://www.kfit.com.cn/"//网站链接

            );

 

            return apiInfo;

        }

 

        private ApiInfo demoApiInfo() {

            ApiInfo apiInfo = new ApiInfo("Demo相关接口",//大标题

                    "Demo相关接口,获取个数,获取列表,注意:",//小标题

                    "1.0",//版本

                    "http://412887952-qq-com.iteye.com/",

                    "Angel",//作者

                    "北京知远信息科技有限公司",//链接显示文字

                    "http://www.kfit.com.cn/"//网站链接

            );

 

            returnapiInfo;

        }

   

}

       上代码所示,通过@Configuration注解,让Spring来加载该类配置。再通过@EnableSwagger2注解来启用Swagger2

       再通过createRestApi函数创建DocketBean之后,apiInfo()用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。select()函数返回一个ApiSelectorBuilder实例用来控制哪些接口暴露给Swagger来展现

       经过这2步配置后,我们启动服务后,访问:http://localhost:8080/swagger-ui.html 就完成了集成。

       下面编写2controller进行测试;

6)编写Controller测试类;

com.kfit.controller.TestController

package com.kfit.controller;

 

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.ResponseBody;

 

import io.swagger.annotations.ApiOperation;

import io.swagger.annotations.ApiParam;

 

/**

 * Swagger2默认将所有的Controller中的RequestMapping方法都会暴露,然而在实际开发中,我们并不一定需要把所有API都提现在文档中查看,这种情况下,使用注解@ApiIgnore来解决,如果应用在Controller范围上,则当前Controller中的所有方法都会被忽略,如果应用在方法上,则对应用的方法忽略暴露API

 

注解@ApiOperation@ApiParam可以理解为API说明,多动手尝试就很容易理解了。

如果我们不使用这样注解进行说明,Swagger2也是有默认值的,没什么可说的试试就知道了。

 

http://localhost:8080/swagger-ui.html 显示页面的右上角有api_key springfox-swagger 2.2.2 版本并没有进行处理,我们可以自己添加拦截器拦截 /v2/api-docs来处理我们API文档的访问权限,如果要更严格更灵活的控制,可能需要修改源码来实现了。相信 springfox-swagger 的后期版本应该会支持更全面的应用需求的。

 *

 * @author Angel(QQ:412887952)

 * @version v.0.1

 */

@Controller

@RequestMapping("/api/test")

public class TestController {

 

    @ResponseBody

    @RequestMapping(value = "/show", method=RequestMethod.POST)// 这里指定RequestMethod,如果不指定Swagger会把所有RequestMethod都输出,在实际应用中,具体指定请求类型也使接口更为严谨。

    @ApiOperation(value="测试接口", notes="测试接口详细描述")

    public String show(

            @ApiParam(required=true, name="name", value="姓名")

            @RequestParam(name = "name") String stuName){

        return "success";

    }

}

 

com.kfit.bean.Demo

package com.kfit.bean;

 

/**

 *

 * @author Angel --守护天使

 * @version v.0.1

 * @date 201697

 */

public class Demo {

    private long id;

    private String name;

    private String content;

    public long getId() {

       return id;

    }

    public void setId(longid) {

       this.id = id;

    }

    public String getName() {

       return name;

    }

    public void setName(String name) {

       this.name = name;

    }

    public String getContent() {

       return content;

    }

    public void setContent(String content) {

       this.content = content;

    }

   

}

 

com.kfit.controller.DemoController

package com.kfit.controller;

 

import java.util.ArrayList;

import java.util.List;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

 

import org.json.JSONObject;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.http.HttpEntity;

import org.springframework.http.HttpHeaders;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.stereotype.Controller;

import org.springframework.ui.ModelMap;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.ResponseBody;

 

import com.kfit.bean.Demo;

 

import io.swagger.annotations.ApiOperation;

import springfox.documentation.annotations.ApiIgnore;

 

/**

 * DemoController

 *

 */

@Controller

@RequestMapping(value = "/demo")

public class DemoController {

 

    private Logger logger = LoggerFactory.getLogger(DemoController.class);

 

    /**

     * 可以直接使用@ResponseBody响应JSON

     *

     * @param request

     * @param response

     * @return

     */

    @ResponseBody

    @RequestMapping(value = "/getcount", method = RequestMethod.POST)

    @ApiOperation(value="测试-getCount", notes="getCount更多说明")

    public ModelMap getCount(HttpServletRequest request,

            HttpServletResponse response) {

        logger.info(">>>>>>>> begin getCount >>>>>>>>");

        ModelMap map = new ModelMap();

        map.addAttribute("count", 158);

 

        // 后台获取的国际化信息

        map.addAttribute("xstest", "测试");

        return map;

    }

 

    /**

     * 可以直接使用@ResponseBody响应JSON

     *

     * @param request

     * @param response

     * @return

     */

    @ApiIgnore//使用该注解忽略这个API

    @ResponseBody

    @RequestMapping(value = "/jsonTest1", method = RequestMethod.POST)

    public ModelMap jsonTest(HttpServletRequest request,

            HttpServletResponse response) {

        ModelMap map = new ModelMap();

        map.addAttribute("hello", "你好");

        map.addAttribute("veryGood", "很好");

 

        return map;

    }

 

    /**

     * 可以直接使用@ResponseBody响应JSON

     *

     * @param request

     * @param response

     * @return

     */

    @ResponseBody

    @RequestMapping(value = "/jsonTest3", method = RequestMethod.POST)

    public List<String> jsonTest3(HttpServletRequest request,

            HttpServletResponse response) {

        List<String> list = new ArrayList<String>();

        list.add("hello");

        list.add("你好");

        return list;

    }

 

    /**

     * JSON请求一个对象<br/>

     * Ajax Post Data{"name":"名称","content":"内容"}

     *

     * @param version

     * @return

     */

    @ResponseBody

    @RequestMapping(value = "/jsonTest2", method = RequestMethod.POST)

    public ModelMap jsonTest2(@RequestBody Demo demo) {

        logger.info("demoName" + demo.getName());

        logger.info("demoContent" + demo.getContent());

        ModelMap map = new ModelMap();

        map.addAttribute("result", "ok");

        return map;

    }

 

    /**

     * 直接读取URL参数值<br/>

     * /demo/jsonTest6.do?name=Hello&content=World

     *

     * @param demoName

     * @param content

     * @return

     */

    @ResponseBody

    @RequestMapping(value = "/jsonTest6", method = RequestMethod.POST)

    public ModelMap jsonTest6(@RequestParam("name") String demoName, @RequestParam String content) {

        logger.info("demoName" + demoName);

        ModelMap map = new ModelMap();

        map.addAttribute("name",demoName + "AAA");

        map.addAttribute("content",content + "BBB");

        map.addAttribute("date",new java.util.Date());

        return map;

    }

 

    /**

     * JSON请求一个对象,将RequestBody自动转换为JSONObject对象<br/>

     * Ajax Post Data{"name":"名称","content":"内容"}

     *

     * 使用JSONObject请添加依赖

     *  <dependency>

     *      <groupId>net.sf.json-lib</groupId>

     *      <artifactId>json-lib</artifactId>

     *      <version>2.4</version>

     *      <!--指定jdk版本 -->

     *      <classifier>jdk15</classifier>

     *  </dependency>

     *

     * @param version

     * @return

     */

    @ResponseBody

    @RequestMapping(value = "/jsonTest5", method = RequestMethod.POST)

    public ModelMap jsonTest5(@RequestBody JSONObject jsonObject) {

        String name = jsonObject.getString("name");

        logger.info("demoName" + name);

        ModelMap map = new ModelMap();

        map.addAttribute("demoName",name);

        return map;

    }

 

    /**

     * 输入和输出为JSON格式的数据的方式 HttpEntity<?> ResponseEntity<?>

     *

     * @param u

     * @return

     */

    @ResponseBody

    @RequestMapping(value = "/jsonTest4", method = RequestMethod.POST)

    public ResponseEntity<String> jsonTest4(HttpEntity<Demo> demo,

            HttpServletRequest request, HttpSession session) {

        //获取Headers方法

        HttpHeaders headers = demo.getHeaders();

 

        // 获取内容

        String demoContent = demo.getBody().getContent();

 

        // 这里直接new一个对象(HttpHeaders headers = new HttpHeaders();

        HttpHeaders responseHeaders = new HttpHeaders();

        responseHeaders.add("MyHeaderName", "SHANHY");

 

        ResponseEntity<String> responseResult = new ResponseEntity<String>(

                demoContent, responseHeaders, HttpStatus.OK);

        return responseResult;

    }

 

}

       Swagger2默认将所有的Controller中的RequestMapping方法都会暴露,然而在实际开发中,我们并不一定需要把所有API都提现在文档中查看,这种情况下,使用注解@ApiIgnore来解决,如果应用在Controller范围上,则当前Controller中的所有方法都会被忽略,如果应用在方法上,则对应用的方法忽略暴露API

       在访问http://localhost:8080/swagger-ui.html就可以看到如下效果:



 

视频&交流平台

à SpringBoot网易云课堂视频

http://study.163.com/course/introduction.htm?courseId=1004329008

à Spring Boot交流平台

http://412887952-qq-com.iteye.com/blog/2321532

 

 

猜你喜欢

转载自412887952-qq-com.iteye.com/blog/2323222