zhihu-spider之Swagger——zhihu-spider开源项目使用技术详解(其二)

来源:互联网 发布:js 浮点数 编辑:程序博客网 时间:2024/05/23 20:03

zhihu-spider之Swagger——zhihu-spider开源项目使用技术详解(其二)

1.Swagger简介

  Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件,它能够允许我们在一个HTML5 Web页面中,对API进行文档化和交互。

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

  官方地址:https://swagger.io/

  github地址:https://github.com/swagger-api

  官方注解文档:http://docs.swagger.io/swagger-core/apidocs/index.html

2.集成Swagger-Spring MVC

1>.添加依赖

//gradle依赖如下compile "io.springfox:springfox-swagger2:2.6.1"compile "io.springfox:springfox-swagger-ui:2.6.1"//maven依赖如下<dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-swagger2</artifactId>    <version>2.6.1</version></dependency><dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-swagger-ui</artifactId>    <version>2.6.1</version></dependency>

2>.增加配置

//Swagger配置文件SwaggerDocumentationConfig.javaimport org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import springfox.documentation.builders.ApiInfoBuilder;import springfox.documentation.builders.RequestHandlerSelectors;import springfox.documentation.service.ApiInfo;import springfox.documentation.service.Contact;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;import springfox.documentation.swagger2.annotations.EnableSwagger2;@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2017-06-06T20:25:53.736+08:00")/** * Swagger配置 *  * @author sunzc * *         2017年6月10日 上午9:42:28 */@Configuration@EnableSwagger2public class SwaggerDocumentationConfig {    ApiInfo apiInfo() {        return new ApiInfoBuilder().title("WeiYou Zhihu")                .description(                        "No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)")                .license("").licenseUrl("http://unlicense.org").termsOfServiceUrl("").version("1.0.0")                .contact(new Contact("", "", "")).build();    }    @Bean    public Docket customImplementation() {        return new Docket(DocumentationType.SWAGGER_2).select()                .apis(RequestHandlerSelectors.basePackage("com.wei.you.zhihu.spider.controller")).build()                .directModelSubstitute(org.joda.time.LocalDate.class, java.sql.Date.class)                .directModelSubstitute(org.joda.time.DateTime.class, java.util.Date.class).apiInfo(apiInfo());    }}

3.Swagger文档编辑

  编辑工具:http://editor.swagger.io/

  文档语法:https://swagger.io/specification/

1>.Swagger-Editor编辑生成的swagger.yml源码

swagger: '2.0'info:  title: WeiYou Zhihu  version: 1.0.0host: '127.0.0.1:8080'schemes:  - httpbasePath: /weiyou/zhihu/v1/produces:  - application/jsonpaths:  /user/list:    get:      tags:         - ZhihuUser      summary: 用户展示      description: 知乎用户列表      parameters:        - name: start          in: query          type: number          description: 起始页          required: true        - name: size          in: query          type: number          description: 页展示数          required: true        - name: filter          in: query          type: string          description: 过滤条件          required: false      responses:        '200':          description: 返回应用服务器的请求列表          schema:            $ref: '#/definitions/ResultDTO'        default:          description: 返回错误信息  /user/add:    post:      tags:         - ZhihuUser      summary: 用户新增      description: 用户新增      parameters:        - name: name          in: query          type: string          description: 用户名          required: true        - name: sex          in: query          type: string          description: 用户性别          required: false        - name: agentId          in: query          type: string          description: 应用agentId          required: true        - name: spanId          in: query          type: number          description: 调用栈spanId          required: true      responses:        '200':          description: 返回应用服务器的请求列表          schema:            $ref: '#/definitions/ResultDTO'        default:          description: 返回错误信息  /user/edit:    put:      tags:         - ZhihuUser      summary: 用户修改      description: 用户修改      parameters:        - name: id          in: query          type: string          description: 用户id          required: true        - name: name          in: query          type: string          description: 用户名          required: true        - name: sex          in: query          type: string          description: 用户性别          required: false        - name: agentId          in: query          type: string          description: 应用agentId          required: true        - name: spanId          in: query          type: number          description: 调用栈spanId          required: true      responses:        '200':          description: 返回应用服务器的请求列表          schema:            $ref: '#/definitions/ResultDTO'        default:          description: 返回错误信息  /user/delete:    delete:      tags:         - ZhihuUser      summary: 用户删除      description: 用户删除      parameters:        - name: id          in: query          type: string          description: 用户id          required: true      responses:        '200':          description: 返回应用服务器的请求列表          schema:            $ref: '#/definitions/ResultDTO'        default:          description: 返回错误信息  /question/list:    get:      tags:         - ZhihuQuestion      summary: 知乎问题      description: 知乎问题列表      parameters:        - name: start          in: query          type: number          description: 起始页          required: true        - name: size          in: query          type: number          description: 页展示数          required: true        - name: filter          in: query          type: string          description: 过滤条件          required: false      responses:        '200':          description: 应用服务器的应用信息列表          schema:            $ref: '#/definitions/ResultDTO'        default:          description: 返回错误信息  /question/add:    post:      tags:         - ZhihuQuestion      summary: 知乎问题新增      description: 知乎问题新增      parameters:        - name: question          in: query          type: string          description: 问题名称          required: true        - name: questionDestion          in: query          type: string          description: 问题详情          required: false        - name: author          in: query          type: string          description: 问题提出者          required: true        - name: url          in: query          type: string          description: 问题url          required: true      responses:        '200':          description: 应用服务器的应用信息列表          schema:            $ref: '#/definitions/ResultDTO'        default:          description: 返回错误信息  /question/delete:    delete:      tags:         - ZhihuQuestion      summary: 知乎问题删除      description: 知乎问题删除      parameters:        - name: id          in: query          type: string          description: 问题编号          required: true      responses:        '200':          description: 请求访问结果          schema:            $ref: '#/definitions/ResultDTO'        default:          description: 返回错误信息definitions:  ResultDTO:    type: object    discriminator: ResultDTOType    properties:      result:        type: string        description: 返回编码      errorMsg:        type: string        description: 返回错误信息

2>.接口定义图形化示例

接口定义图形化示例

3>.文档编写后,生成Spring代码

在该编辑页面选择【Generate Server】->【Spring】,生成的代码会自动下载。重点是接口Api。

//知乎问答API生成代码QuestionApi.javaimport java.math.BigDecimal;import io.swagger.model.InlineResponse200;import io.swagger.annotations.*;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestHeader;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.RequestPart;import org.springframework.web.multipart.MultipartFile;import java.util.List;import javax.validation.constraints.*;@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2017-07-01T01:50:42.498Z")@Api(value = "question", description = "the question API")public interface QuestionApi {    @ApiOperation(value = "知乎问题新增", notes = "知乎问题新增", response = InlineResponse200.class, tags={ "ZhihuQuestion", })    @ApiResponses(value = {         @ApiResponse(code = 200, message = "应用服务器的应用信息列表", response = InlineResponse200.class),        @ApiResponse(code = 200, message = "返回错误信息", response = InlineResponse200.class) })    @RequestMapping(value = "/question/add",        produces = { "application/json" },         method = RequestMethod.POST)    ResponseEntity<InlineResponse200> questionAddPost( @NotNull @ApiParam(value = "问题名称", required = true) @RequestParam(value = "question", required = true) String question,         @NotNull @ApiParam(value = "问题提出者", required = true) @RequestParam(value = "author", required = true) String author,         @NotNull @ApiParam(value = "问题url", required = true) @RequestParam(value = "url", required = true) String url,         @ApiParam(value = "问题详情") @RequestParam(value = "questionDestion", required = false) String questionDestion);    @ApiOperation(value = "知乎问题删除", notes = "知乎问题删除", response = InlineResponse200.class, tags={ "ZhihuQuestion", })    @ApiResponses(value = {         @ApiResponse(code = 200, message = "请求访问结果", response = InlineResponse200.class),        @ApiResponse(code = 200, message = "返回错误信息", response = InlineResponse200.class) })    @RequestMapping(value = "/question/delete",        produces = { "application/json" },         method = RequestMethod.DELETE)    ResponseEntity<InlineResponse200> questionDeleteDelete( @NotNull @ApiParam(value = "问题编号", required = true) @RequestParam(value = "id", required = true) String id);    @ApiOperation(value = "知乎问题", notes = "知乎问题列表", response = InlineResponse200.class, tags={ "ZhihuQuestion", })    @ApiResponses(value = {         @ApiResponse(code = 200, message = "应用服务器的应用信息列表", response = InlineResponse200.class),        @ApiResponse(code = 200, message = "返回错误信息", response = InlineResponse200.class) })    @RequestMapping(value = "/question/list",        produces = { "application/json" },         method = RequestMethod.GET)    ResponseEntity<InlineResponse200> questionListGet( @NotNull @ApiParam(value = "起始页", required = true) @RequestParam(value = "start", required = true) BigDecimal start,         @NotNull @ApiParam(value = "页展示数", required = true) @RequestParam(value = "size", required = true) BigDecimal size,         @ApiParam(value = "过滤条件") @RequestParam(value = "filter", required = false) String filter);}//用户API生成代码UserApi.javaimport java.math.BigDecimal;import io.swagger.model.InlineResponse200;import io.swagger.annotations.*;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestHeader;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.RequestPart;import org.springframework.web.multipart.MultipartFile;import java.util.List;import javax.validation.constraints.*;@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2017-07-01T01:50:42.498Z")@Api(value = "user", description = "the user API")public interface UserApi {    @ApiOperation(value = "用户新增", notes = "用户新增", response = InlineResponse200.class, tags={ "ZhihuUser", })    @ApiResponses(value = {         @ApiResponse(code = 200, message = "返回应用服务器的请求列表", response = InlineResponse200.class),        @ApiResponse(code = 200, message = "返回错误信息", response = InlineResponse200.class) })    @RequestMapping(value = "/user/add",        produces = { "application/json" },         method = RequestMethod.POST)    ResponseEntity<InlineResponse200> userAddPost( @NotNull @ApiParam(value = "用户名", required = true) @RequestParam(value = "name", required = true) String name,         @NotNull @ApiParam(value = "应用agentId", required = true) @RequestParam(value = "agentId", required = true) String agentId,         @NotNull @ApiParam(value = "调用栈spanId", required = true) @RequestParam(value = "spanId", required = true) BigDecimal spanId,         @ApiParam(value = "用户性别") @RequestParam(value = "sex", required = false) String sex);    @ApiOperation(value = "用户删除", notes = "用户删除", response = InlineResponse200.class, tags={ "ZhihuUser", })    @ApiResponses(value = {         @ApiResponse(code = 200, message = "返回应用服务器的请求列表", response = InlineResponse200.class),        @ApiResponse(code = 200, message = "返回错误信息", response = InlineResponse200.class) })    @RequestMapping(value = "/user/delete",        produces = { "application/json" },         method = RequestMethod.DELETE)    ResponseEntity<InlineResponse200> userDeleteDelete( @NotNull @ApiParam(value = "用户id", required = true) @RequestParam(value = "id", required = true) String id);    @ApiOperation(value = "用户修改", notes = "用户修改", response = InlineResponse200.class, tags={ "ZhihuUser", })    @ApiResponses(value = {         @ApiResponse(code = 200, message = "返回应用服务器的请求列表", response = InlineResponse200.class),        @ApiResponse(code = 200, message = "返回错误信息", response = InlineResponse200.class) })    @RequestMapping(value = "/user/edit",        produces = { "application/json" },         method = RequestMethod.PUT)    ResponseEntity<InlineResponse200> userEditPut( @NotNull @ApiParam(value = "用户id", required = true) @RequestParam(value = "id", required = true) String id,         @NotNull @ApiParam(value = "用户名", required = true) @RequestParam(value = "name", required = true) String name,         @NotNull @ApiParam(value = "应用agentId", required = true) @RequestParam(value = "agentId", required = true) String agentId,         @NotNull @ApiParam(value = "调用栈spanId", required = true) @RequestParam(value = "spanId", required = true) BigDecimal spanId,         @ApiParam(value = "用户性别") @RequestParam(value = "sex", required = false) String sex);    @ApiOperation(value = "用户展示", notes = "知乎用户列表", response = InlineResponse200.class, tags={ "ZhihuUser", })    @ApiResponses(value = {         @ApiResponse(code = 200, message = "返回应用服务器的请求列表", response = InlineResponse200.class),        @ApiResponse(code = 200, message = "返回错误信息", response = InlineResponse200.class) })    @RequestMapping(value = "/user/list",        produces = { "application/json" },         method = RequestMethod.GET)    ResponseEntity<InlineResponse200> userListGet( @NotNull @ApiParam(value = "起始页", required = true) @RequestParam(value = "start", required = true) BigDecimal start,         @NotNull @ApiParam(value = "页展示数", required = true) @RequestParam(value = "size", required = true) BigDecimal size,         @ApiParam(value = "过滤条件") @RequestParam(value = "filter", required = false) String filter);}

4.设定访问API doc的路由

在配置文件中,application.yml中声明:

#这个path就是json的访问request mapping.可以自定义,防止与自身代码冲突。springfox:  documentation:    swagger:      v2:        path: /api-docs#API doc的显示路由是:http://localhost:8080/swagger-ui.html        

如果项目是一个webservice,通常设定home / 指向这里:

@Controllerpublic class HomeController {    @RequestMapping(value = "/swagger")    public String index() {        System.out.println("swagger-ui.html");        return "redirect:swagger-ui.html";    }}

5.项目的开源地址

https://github.com/sdc1234/zhihu-spider