SpringBoot之整合Swagger2

1、問題描述

隨着互聯網技術的發展,如今的網站架構基本都由原來的後端渲染,變成了:前端渲染、前後端分離的形態,並且前端技術和後端技術在各自的道路上越走越遠。 前端和後端的惟一聯繫,變成了API接口;API文檔變成了先後端開發人員聯繫的紐帶,變得愈來愈重要,swagger就是一款讓你更好的書寫API文檔的框架,並且swagger能夠徹底模擬http請求,入參出參和實際狀況差異幾乎爲零。html

  沒有API文檔工具以前,你們都是手寫API文檔的(維護起來至關困難),在什麼地方書寫的都有,有在confluence上寫的,有在對應的項目目錄下readme.md上寫的,每一個公司都有每一個公司的玩法,無所謂好壞。可是能稱之爲「框架」的,估計也只有swagger了前端

2、使用步驟

  1. 建立springboot項目配置pom.xml
<dependency>
            <!--添加lombok就能夠不用再寫set,get方法-->
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
  1. 配置啓動類
package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

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

}
  1. 建立Swagger的配置類
package com.example.config;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Autowired
    Environment environment;
    //配置Docket以配置Swagger具體參數

    //在不一樣生產模式下的操做,
//    @Bean
//    public Docket docket(){
//        Profiles profiles=Profiles.of("dev","test");
//        boolean isEnable = environment.acceptsProfiles(profiles);
//        return new Docket(DocumentationType.SWAGGER_2)
//                .ignoredParameterTypes(Integer.class,Long.class, HttpSession.class)
//                .enable(isEnable);
//    }


//    @Bean
//    public Docket docketUser(){
//        Parameter token= new ParameterBuilder().name("token")
//                .description("用戶登陸令牌")
//                .parameterType("header")
//                .modelRef(new ModelRef("String"))
//                .required(true)
//                .build();
//        List<Parameter> parameters=new ArrayList<>();
//        parameters.add(token);
//        return new Docket(DocumentationType.SWAGGER_2)
//                .globalOperationParameters(parameters);
//    }


    //基於包
    @Bean
    public Docket docket(){
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
//        return new Docket(DocumentationType.SWAGGER_2)
//                .select()
//                .apis(RequestHandlerSelectors.basePackage("com.example.controller"))
//                //paths能夠進行篩選想要的方法
//                .paths(PathSelectors.ant("/hello/**"))
//                .build();
    }

    //基於方法
//    @Bean
//    public Docket docket(){
//        return new Docket(DocumentationType.SWAGGER_2)
//                .select()
//                .apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class)).build();
//    }

    private ApiInfo apiInfo(){
        Contact contact=new Contact("小謝","aaa.com","1787798327@qq.com");
        return new ApiInfo("Swagger學習接口文檔",
                "這是學習swagger時生成的文檔信息",
                "v1.0",
                "http://xietongxue.top:8090",
                contact,
                "",
                "",
                new ArrayList<>()
        );
    }



}

1

  1. 建立User
package com.example.model;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("用戶實體")
public class User {
    @ApiModelProperty(value = "用戶id",example = "0")
    private Integer id;
    @ApiModelProperty("用戶名")
    private String username;
    @ApiModelProperty(value = "用戶年齡",example = "1")
    private String age;
}
  1. 建立Controller
package com.example.controller;

import com.example.model.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

@Api(tags = "用戶相關的請求")
@RestController
@RequestMapping("/user")
public class UserController {

    @ApiOperation("獲取用戶信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username",value = "用戶名",
                    dataType = "string",paramType = "header",defaultValue = "zhangsan",example = "lisi"),
            @ApiImplicitParam(name = "password",value = "用戶密碼")
    })

    @GetMapping
    public String getUser(String username,String password){
        return "user";
    }

    @ApiOperation("添加用戶")
    @PostMapping
    public User postUser(User user){
        return user;
    }

    @ApiOperation("刪除用戶")
    @DeleteMapping
    public User delUser(@RequestBody User user){
        return user;
    }




//    @GetMapping
//    public String getUser(){
//        return "張三";
//    }
//
//    @PostMapping
//    public String addUser(String username){
//        return username;
//    }
//
//    @DeleteMapping
//    public User delUser(){
//        User zs = new User("張三", "15");
//        return zs;
//    }
//
//    @PutMapping
//    public String putUser(@RequestBody User user){
//        return "user";
//    }
}

2

  1. 啓動測試http://localhost:8080/swagger-ui.html

在這裏插入圖片描述

部分代碼精講

除了經過包路徑配置掃描接口外,還能夠經過配置其餘方式掃描接口,這裏註釋一下全部的配置方式:web

any() // 掃描全部,項目中的全部接口都會被掃描到
none() // 不掃描接口
withMethodAnnotation(final Class<? extends Annotation> annotation)// 經過方法上的註解掃描,如withMethodAnnotation(GetMapping.class)只掃描get請求
withClassAnnotation(final Class<? extends Annotation> annotation) // 經過類上的註解掃描,如.withClassAnnotation(Controller.class)只掃描有controller註解的類中的接口
basePackage(final String basePackage) // 根據包路徑掃描接口

一、配置接口掃描過濾
上述方式能夠經過具體的類、方法等掃描接口,還能夠配置如何經過請求路徑配置:正則表達式

eturn new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller"))
                // 配置如何經過 path過濾 即這裏只掃描 請求以 /user開頭的接口
               .paths(PathSelectors.ant("/user/**"))
                .build();

這裏的可選值還有:spring

any() // 任何請求都掃描
none() // 任何請求都不掃描
regex(final String pathRegex) // 經過正則表達式控制,返回true掃描,false不掃描
ant(final String antPattern) // 經過ant()表達式控制,返回true掃描,false不掃描

二、配置要忽略的請求參數
能夠經過ignoredParameterTypes()方法去配置要忽略的參數:後端

// 配置docket以配置Swagger具體參數
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
            // 配置要忽略的參數
                .ignoredParameterTypes(HttpServletRequest.class) 
                .select()
       .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller")).build();
    }

三、配置是否啓動Swagger
經過enable()方法配置是否啓用swagger,若是是false,swagger將不能在瀏覽器中訪問了:api

@Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                .ignoredParameterTypes(HttpServletRequest.class)
                .enable(false) // 配置是否啓用Swagger,若是是false,在瀏覽器將沒法訪問
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller")).build();
    }

**四、如何動態配置當項目處於test、dev環境時顯示swagger,處於prod時不顯示?
**瀏覽器

@Bean
    public Docket docket(Environment environment) {
        // 設置要顯示swagger的環境
        Profiles of = Profiles.of("dev", "test");
        // 判斷當前是處於該環境,經過 enable() 接收此參數判斷是否要顯示
        boolean b = environment.acceptsProfiles(of);

        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                .ignoredParameterTypes(HttpServletRequest.class)
                .enable(b) // 配置是否啓用Swagger,若是是false,在瀏覽器將沒法訪問
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.swaggerexample.controller")).build();
    }

五、配置API分組
若是沒有配置分組,默認是default。經過groupName()方法便可配置分組:springboot

//配置分組
    @Bean
    public Docket docketUser(){
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("用戶")
                .select().paths(PathSelectors.ant("/user")).build();
    }

    @Bean
    public Docket docketHello(){
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("你好")
                .select().paths(PathSelectors.ant("/hello")).build();
    }

以下圖所示,咱們配置了groupName("user")那麼當前接口分組信息爲user。
4架構

六、實體配置
好比當前項目中有這麼一個實體:

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("用戶實體")
public class User {
    @ApiModelProperty(value = "用戶id",example = "0")
    private Integer id;
    @ApiModelProperty("用戶名")
    private String username;
    @ApiModelProperty(value = "用戶年齡",example = "1")
    private String age;
}

只要這個實體在請求接口的返回值上(即便是泛型),都能映射到實體項中:

5
注:並非由於@ApiModel這個註解讓實體顯示在這裏了,而是隻要出如今接口方法的返回值上的實體都會顯示在這裏,而@ApiModel和@ApiModelProperty這兩個註解只是爲實體添加註釋的。
@ApiModel爲類添加註釋
@ApiModelProperty爲類屬性添加註釋

經常使用的註解

swagger經過註解代表該接口文檔會生成文檔,包括接口名,請求方法,參數,返回信息的等等。
@Api修飾整個類,描述controller的做用
@ApiOperation:描述一個類的一個方法,或者說一個接口
@ApiParam:單個參數描述
@ApiModel:當接收參數爲對象時
@ApiProperty:用對象接收參數時,描述對象的一個字段
@ApiRespose:HTTP響應其中1個描述
@ApiResponses:HTTP響應總體描述
@ApiIgnore:使用該註解忽略這個API
@ApiError:發生錯誤返回的信息
@ApiImplicitParam:一個參數請求
@ApiImplicitParams:多個請求
詳細解釋:
@Api:用在請求類上,表示對類的說明
tags=「說明該類的做用,能夠在UI界面上看到的註解」
value=「該參數沒什麼意義,在UI界面上也看到,因此不須要配置」
@ApiOperation:用在請求的方法上,說明方法的用途,做用
value=「說明方法的用途,做用」
notes=「方法的備註說明」
@ApiImplicitParams:用在請求的方法上,表示一組參數的說明
@ApiImplicitParam:用在@ApiImplicitParams註解中,指定一個請求參數的各個方面
name:參數名
value:參數的漢字說明
required:參數放在哪一個地方

header:請求參數的獲取 @RequestHeader
query:請求參數的獲取 @RequestParam
path:(用於Restful接口)
body(不經常使用)
form(不經常使用)
dataTye:當參數爲對象類型時指定參數類型
@ApiResponses:用在請求的方法上,表示一組響應
@ApiResponse:用在@ApiResponses中,通常用於表達一個錯誤的響應信息(實際上任何相應信息均可以)
code:數字,例如400
message:信息,例如「請求參數沒填寫正確」
response:拋出的異常類

@ApiModel:用於響應類上,表示一個返回響應數據的信息(這種通常用在post建立的時候,使用@RequestBody這樣的場景,請求參數沒法使用@ApiImplicitParams註解進行描述的時候)
@ApiModelProperty:用在屬性上,描述響應類的屬性
相關文章
相關標籤/搜索