首先Swagger它是一个API文档工具,可以通过各种注解生成接口文档,Model文档,但是我在使用Swagger的时候,觉得实用性并不高,一个机会接触到了基于Swagger开发的Swagger-Bootstrap-UI,觉得很好用.

1.引入依赖

<properties>
    <swagger.version>2.9.2</swagger.version>
    <xiaoymin.version>1.9.2</xiaoymin.version>
</properties>

<!--swagger-api-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>${swagger.version}</version>
</dependency>
<!--swagger-bootstrap-ui-->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>swagger-bootstrap-ui</artifactId>
    <version>${xiaoymin.version}</version>
</dependency>

2.配置类

import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import io.swagger.annotations.ApiOperation;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.Collections;

/**
 * Swagger配置
 *
 * @author Wcy
 * @date 2020/8/19 20:53
 */
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
@ConfigurationProperties(prefix = "swagger")
public class SwaggerConfig {

    //bootstrap-ui
    @Bean
    public Docket examApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .groupName("考试模块接口")
                .host("http://666.66.66.666:8081")
                .select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.ant("/exam/api/**"))
                .build()

                .securitySchemes(Collections.singletonList(securityScheme()));
    }


    //swagger-ui
    private ApiInfo apiInfo() {
        return new
                ApiInfoBuilder().title("考试系统接口")
                .description("考试系统接口")
                .contact(new Contact("Wcy", "url", "email"))
                .version("1.0.0")
                .build()
                ;
    }


    /**
     * 授权头部
     *
     * @return
     */
    @Bean
    SecurityScheme securityScheme() {
        return new ApiKey("token", "token", "header");
    }

}

ShiroConfig配置类

import com.yf.exam.modules.shiro.ShiroRealm;
import com.yf.exam.modules.shiro.aop.JwtFilter;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;


/**
 * Shiro配置类
 *
 * @author Wcy
 */
@Slf4j
@Configuration
public class ShiroConfig {

    /**
     * Filter Chain定义说明
     * <p>
     * 1、一个URL可以配置多个Filter,使用逗号分隔
     * 2、当设置多个过滤器时,全部验证通过,才视为通过
     * 3、部分过滤器可指定参数,如perms,roles
     */
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 拦截器
        Map<String, String> map = new LinkedHashMap<>();

        // 需要排除的一些接口
        map.put("/exam/api/sys/user/login", "anon");
        map.put("/exam/api/sys/user/reg", "anon");
        map.put("/exam/api/sys/user/quick-reg", "anon");

        // 获取网站基本信息
        map.put("/exam/api/sys/config/detail", "anon");

        // 文件读取
        map.put("/upload/file/**", "anon");

        map.put("/", "anon");
        map.put("/v2/**", "anon");
        map.put("/doc.html", "anon");
        map.put("/**/*.js", "anon");
        map.put("/**/*.css", "anon");
        map.put("/**/*.html", "anon");
        map.put("/**/*.svg", "anon");
        map.put("/**/*.pdf", "anon");
        map.put("/**/*.jpg", "anon");
        map.put("/**/*.png", "anon");
        map.put("/**/*.ico", "anon");

        // 字体
        map.put("/**/*.ttf", "anon");
        map.put("/**/*.woff", "anon");
        map.put("/**/*.woff2", "anon");
        map.put("/druid/**", "anon");
        map.put("/swagger-ui.html", "anon");
        map.put("/swagger**/**", "anon");
        map.put("/webjars/**", "anon");

        // 添加自己的过滤器并且取名为jwt
        Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
        filterMap.put("jwt", new JwtFilter());
        shiroFilterFactoryBean.setFilters(filterMap);
        map.put("/**", "jwt");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    @Bean("securityManager")
    public DefaultWebSecurityManager securityManager(ShiroRealm myRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myRealm);
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);
        return securityManager;
    }

    /**
     * 下面的代码是添加注解支持
     *
     * @return
     */
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        defaultAdvisorAutoProxyCreator.setUsePrefix(true);
        defaultAdvisorAutoProxyCreator.setAdvisorBeanNamePrefix("_no_advisor");
        return defaultAdvisorAutoProxyCreator;
    }

    @Bean
    public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

}

配置好后,将项目启动,访问
http://localhost:8081/doc.html

如下图,即成功:


在进到这个页面以后,可以去往网络doc.html的标头里获取token填到Authorize里面便可以进行接口调试

3.常用注解

swagger得注解其实有很多,但是没必要每一个都去掌握,掌握几个最实用得注解就好了,其他得注解可以在学习或者工作得过程中去了解,我们可以打开它得引入得jar大概得了解一下,让自己心里有个数:
请输入图片描述

3.1.Api类注解

3.1.1.@Api
@Api顾名思义,它就是打在接口(controller类)上的注解。

@Api(tags = "用户管理")



3.1.2.@ApiOperation
@ApiOperation这个注解,打在接口里得方法上,与@Api注解结合使用

@ApiOperation(value = "新增用户")

如果你不希望某个接口通过这个文档暴露出去,可以这样

@ApiOperation(value = "批量新增用户", hidden = true)


3.2.Model类注解

Model类得注解主要是使用在一些entity,dto,vo,model上,可以在swagger-bootstrap-UI里得swagger-models里查看,可以在接口里的请求实例或者响应示例里查看

3.2.1.@ApiModel

@ApiModel(value="SysUser对象")

下面给出两个实例:


3.2.2.@ApiModelProperty
这个注解用来打在entity,vo …这些类得字段上,与@ApiModel注解配合使用

@ApiModelProperty(value = “主键:用户ID”)

如果你不希望某个字段通过这个文档暴露出去,你可以这样

@ApiModelProperty(value = "用户登录密码", hidden = true)


3.3.参数类注解

其实参数类注解之前我也有用过,这个时候我们可以看一下是哪个注解,首先打开jar,找一下:

3.3.1.@ApiParam
@ApiParam就是参数的注解,接下来我们再来看一下这个注解的内容。


value是参数的名称含义了,这个defaultValue和required在@RequestParam注解里都有,它们意思分别是默认值和是否必填,再看hidden和readOnly,一个是隐藏,另一个就是只读,最后我们看一下example,这个是参数的填写示例


然后我们再来看一下hidden属性,加上这个后文档中的这个参数就消失了.

4.接口调试

接口调试的话,打开接口文档,找到调试,填写参数,点击发送即可

5.版本控制

knife4j 使用浏览器的localStorage对象,提供了一个细微的版本控制功能,主要体现在如下两个方面:

后端新增接口是识别出变化
后端接口信息变更是会识别出接口变更
knife4j 判断新接口的依据:接口地址+接口请求类型(POST|GET|PUT…)

而任何元素的变更,包括参数类型、接口说明、响应参数等等元素的变更,knife4j 都能识别出接口的变化,并通过icon图表(new)的方式在接口文档中展示出来

对接接口的开发者只需要刷新当前文档页就能看到后端接口是否新增或修改.

效果图:

相关官方文档可参考:官方文档

最后修改:2022 年 10 月 11 日
如果觉得我的文章对你有用,请随意赞赏