随着互联网技术的发展,如今的网站架构基本都由原来的后端渲染,变成了:前端渲染、前后端分离的形态,并且前端技术和后端技术在各自的道路上越走越远。 前端和后端的惟一联系,变成了API接口;API文档变成了先后端开发人员联系的纽带,变得愈来愈重要,swagger就是一款让你更好的书写API文档的框架,并且swagger能够彻底模拟http请求,入参出参和实际状况差异几乎为零。html
没有API文档工具以前,你们都是手写API文档的(维护起来至关困难),在什么地方书写的都有,有在confluence上写的,有在对应的项目目录下readme.md上写的,每一个公司都有每一个公司的玩法,无所谓好坏。可是能称之为“框架”的,估计也只有swagger了前端
<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>
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); } }
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<>() ); } }
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; }
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"; // } }
除了经过包路径配置扫描接口外,还能够经过配置其余方式扫描接口,这里注释一下全部的配置方式: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。架构
六、实体配置
好比当前项目中有这么一个实体:
@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; }
只要这个实体在请求接口的返回值上(即便是泛型),都能映射到实体项中:
注:并非由于@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:用在属性上,描述响应类的属性