接口可视化工具swagger实现

概述

Swagger是一个接口可视化工具,将项目中的接口通过ui的形式展现出来,因为是实时生成的,所以能够做到在线文档和API始终同步。并且能够对接口进行测试。在接口中我们只要配置对应的项,我们在在线文档中可以查看接口名称,请求参数、请求类型、接口类型、接口描述、返回数据类型、返回格式。

pom依赖

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.0.3</version>
</dependency>
 <dependency>
    <groupId>com.mangofactory</groupId>
    <artifactId>swagger-springmvc</artifactId>
    <version>0.9.5</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.0.3</version>
</dependency>

application.properties配置:配置一些页面显示的信息。

spring.application.name=swagger-service
server.port=8090
server.context-path=/swagger-service

#swagger配置--用英文,中文会乱码
swagger.title=swagger-service API
swagger.description=swagger-service url show
swagger.version=1.0.0
swagger.termsOfServiceUrl=http://jhipster.github.io/
swagger.contact=
swagger.license=Apache 2.0
swagger.licenseUrl=http://www.apache.org/lisenses/LICESE-2.0.html

实现

       首先新建一个类SwaggerConfiguration实现EnvironmentAware。用来配置swagger。swagger提供各种接口配置方式。这里只介绍几种常用的。代码中有详细的介绍。

package com.zhong.demo.swaggerservice.swagger;

import com.google.common.base.Predicates;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StopWatch;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.*;

import static springfox.documentation.builders.PathSelectors.regex;


@Configuration
@EnableSwagger2
@ComponentScan("com.zhong.demo.swaggerservice")
public class SwaggerConfiguration implements EnvironmentAware {

    private final Logger logger = LoggerFactory.getLogger(SwaggerConfiguration.class);

    private RelaxedPropertyResolver relaxedPropertyResolver;

    //可以展示的接口的匹配规则 - 所有接口
    public static final String ALL_PATTEN = "/*/.*";
    //可以展示的接口的匹配规则 - /web/.*
    public static final String WEB_PATTEN = "/web/.*";
    //可以展示的接口的匹配规则 - /api/.*
    public static final String API_PATTEN = "/api/.*";

    //可以展示的接口的匹配规则 - /web/rest/hello
    public static final String API_hello_PATTEN = "/web/rest/hello";

    //可以展示的接口的匹配规则 - /web/rest/hello1
    public static final String API_hello1_PATTEN = "/web/rest/hello1";


    @Override
    public void setEnvironment(Environment environment) {
        //解析配置文件中以 swagger. 开始的配置项
        this.relaxedPropertyResolver = new RelaxedPropertyResolver(environment, "swagger.");
    }

    @Bean
    public Docket swaggerSpringFoxDocket(){
        logger.debug("swagger 开始");
        //StopWatch是位于org.springframework.util包下的一个工具类,通过它可方便的对程序部分代码进行计时(ms级别),适用于同步单线程代码块
        StopWatch watch = new StopWatch();
        watch.start();

        Set<String> set = new HashSet<>();
        set.add(API_hello_PATTEN);
        set.add(API_hello1_PATTEN);
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                //配置api显示信息
                .apiInfo(apiInfo())
                .genericModelSubstitutes(ResponseEntity.class)
                .forCodeGeneration(true)
                .genericModelSubstitutes(ResponseEntity.class)
                .directModelSubstitute(org.joda.time.LocalDateTime.class, String.class)
                .directModelSubstitute(org.joda.time.LocalTime.class, Date.class)
                .directModelSubstitute(org.joda.time.LocalDate.class, Date.class)
                .directModelSubstitute(org.joda.time.LocalDate.class, String.class)
                .directModelSubstitute(org.joda.time.LocalDateTime.class, Date.class)
                .directModelSubstitute(org.joda.time.LocalTime.class, Date.class)
                .select()
                /**
                 * apis()是对方法的选择,可以选择某个jar,选择有注解和类和方法
                 * .apis(RequestHandlerSelectors.basePackage("com.zhong.demo.swaggerservice.web"))   //选择jar
                 *
                 */
                .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))//只生成被Api这个注解注解过的类接口
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))//只生成被ApiOperation这个注解注解过的api接口
                .paths(PathSelectors.any())
                /**
                 * 设置接口匹配规则,只能是一个。
                 *  .paths(regex(ALL_PATTEN)).build();
                 */
                /**
                 * 设置接口匹配规则,可以多个。
                 *  .paths(Predicates.or(regex(WEB_PATTEN),regex(API_PATTEN))).build();
                 *  .paths(Predicates.or(Predicate<? super T>... components))).build();
                 */

                /**
                 * 设置接口匹配规则,指定具体接口。
                 *  .paths(Predicates.in(Predicates.in(Collection)).build()
                 */
                //.paths(Predicates.or(regex(WEB_PATTEN),regex(API_PATTEN)))
                .build();

                //.globalOperationParameters(setHeaderToken());
        watch.stop();
        logger.debug("启动swagger 用时 {} ms", watch.getTotalTimeMillis());
        return docket;

    }

    private ApiInfo apiInfo(){
        //获取api配置信息
        return new ApiInfo(relaxedPropertyResolver.getProperty("title"),
                relaxedPropertyResolver.getProperty("description"),
                relaxedPropertyResolver.getProperty("version"),
                relaxedPropertyResolver.getProperty("termsOfServiceUrl"),
                relaxedPropertyResolver.getProperty("contact"),
                relaxedPropertyResolver.getProperty("license"),
                relaxedPropertyResolver.getProperty("licenseUrl"));
    }

    private List<Parameter> setHeaderToken() {
        ParameterBuilder tokenPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<>();
        tokenPar.name("X-Auth-Token").description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
        pars.add(tokenPar.build());
        return pars;
    }
}

         接下来,写接口。接口和springMVC没有区别。只不过在类上添加@Api(),和在方法上添加@ApiOperation注解,参数上配置@ApiParam。用来告诉swagger怎显示接口。主要是@ApiOperation@ApiParam注解必须要正确。在配合上springMVC的@RequestBody和@PathVariable,这样swagger的ui显示的才能是正确的。以下是一个简单例子:

@RestController
@RequestMapping("/web/rest")
@Api(value="swagger2", description = "web测试接口2")
public class WebController {
    @ResponseBody
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    @ApiOperation(nickname = "api-rest-hello", value = "operationId",
            notes = "get方法获取参数测试,返回Stirng", produces = "application/*",
            consumes = "application/json", response = String.class)
    public Object hello(@ApiParam(value = "请求参数", name = "param", required = true) @RequestParam("param") String param){
        return "收到参数 param="+ param;
    }

    @ResponseBody
    @RequestMapping(value = "/hello1", method = RequestMethod.GET)
    @ApiOperation(nickname = "api-rest-hello1", value = "operationId1",
            notes = "get方法获取参数测试,返回对象", produces = "application/json", httpMethod = "GET",
            consumes = "application/json", response = ReturnBean.class)
    public Object hello1(@ApiParam(value = "请求参数", name = "param", required = true) @RequestParam("param") String param){
        ReturnBean returnBean =new ReturnBean();
        returnBean.setName("swagger测试");
        returnBean.setDate(new Date());
        returnBean.setLocation( "收到参数 param="+ param);
        return returnBean;
    }
}

注解说明

@Api

作用在类上,用来标注该类具体实现内容。表示标识这个类是swagger的资源

tags:可以使用tags()允许您为操作设置多个标签的属性,而不是使用该属性。

description:可描述描述该类作用。

@ApiOperation

@ApiOperation中注解和@RequestMapping很多事相似的。作用也是一样的。其中nickname是一个ui地址。每一个接口的应该是不一样的额, value和notes都是接口描述。@ApiParam中的value是描述, name是参数在ui中显示, required表示是否必填。

    需要注意的是,我们在swaggerSpringFoxDocket()方法中用apis()限制包含对应的注解的方法和类才能显示。所以我们的注解必须包含且注解的类路径必须一致才行。否则就会无法显示。

    做好这些之后,我们启动项目。通过http://localhost:8090/swagger-service/swagger-ui.html#/访问接口数据。得到结果

点开其中的一个接口:

从页面可以看出,几乎包含了我们需要的任何信息。参数类型,参数示例。我们可以按照示例输入参数。点击try it out就能直接调用接口测试了。

不仅如此swagger还可以根据属性的@JsonProperty来改变输入示例。但是发现一个问题就是,时间格式并没有根据@DateTimeFormat(pattern = "yyyyMMddHHmmss")来显示。暂时不知道是为什么。但是是可以转换的。

@ApiModel 和@ApiModelProperty

@ApiModel 和@ApiModelProperty 是对入参对象和返回参数对象的注解,目的是在界面更好展示出参和返回中没有一个属性的含义和取值要求。

@ApiModel 在实体类上边使用,标记类时swagger的解析类提供有关swagger模型的其它信息,类将在操作中用作类型时自动内省

属性

属性名称数据类型默认值说明
valueString类名为模型提供备用名称
descriptionString“”提供详细的类描述
parentClass<?> parentVoid.class为模型提供父类以允许描述继承关系
discriminatoryString“”支持模型继承和多态,使用鉴别器的字段的名称,可以断言需要使用哪个子类型
subTypesClass<?>[]{}从此模型继承的子类型数组
referenceString“”指定对应类型定义的引用,覆盖指定的任何其他元数据

@ApiModelProperty()使用用于方法,字段,在被 @ApiModel 注解的模型类的属性上,作用是可以在文档中展示我们想展示的内容(类型,是否必填,取值要求)

属性

属性名称数据类型默认值说明
valueString“”属性简要说明
nameString“”运行覆盖属性的名称。重写属性名称
allowableValuesString“”限制参数可接收的值,三种方法,固定取值,固定范围
accessString“”过滤属性,参阅:io.swagger.core.filter.SwaggerSpecFilter
notesString“”目前尚未使用
dataTypeString“”参数的数据类型,可以是类名或原始数据类型,此值将覆盖从类属性读取的数据类型
requiredbooleanfalse是否为必传参数,false:非必传参数; true:必传参数
positionint0允许在模型中显示排序属性
hiddenbooleanfalse隐藏模型属性,false:不隐藏; true:隐藏
exampleString“”属性的示例值
readOnlybooleanfalse指定模型属性为只读,false:非只读; true:只读
referenceString“”指定对应类型定义的引用,覆盖指定的任何其他元数据
allowEmptyValuebooleanfalse允许传空值,false:不允许传空值; true:允许传空值

以上就是swagger的简单实现。具体代码已经上传了(https://download.csdn.net/download/qq_34484062/12431589),需要的朋友可以下载试一下。有问题欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值