Knife4j---swagger的进阶版


用原始的swagger,可对于封装map和实体类,jsaonobject的参数不太方便,但是,用knofe4j就可以实现了

查看路径:http://localhost:8181/sa/doc.html

1. pom依赖

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>2.0.8</version>
</dependency>

2.配置

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.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;


@Configuration
@EnableSwagger2WebMvc
public class SwaggerConfig {
    @Bean(value = "api")
    public Docket defaultApi2() {
        Docket docket=new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder()
                        .description("# 文档的描述")
                        .version("1.0")
                        .build())
                 .enable(false) // 关闭swagger
                //分组名称
                .groupName("1.X版本")
                .select()
                //这里指定Controller扫描包路径
                .apis(RequestHandlerSelectors.basePackage("com.ify.sampleAdmin.web.controller"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }
}

3.使用

@RestController
@RequestMapping("/user")
@Api(tags = "用户模块")
public class UserController extends BaseController {
    @GetMapping("/user")
    @ApiOperation(value = "获取根据ID获取用户")
    @ApiImplicitParam(name = "id",value = "用户id",required = true)
    public ResResult getUser(@RequestParam(value = "id") String id) {
        return ResResult.success();
    }
}

如果报错:Failed to start bean ‘documentationPluginsBootstrapper’
就在启动类上加 @EnableWebMvc,并且创建下面的类

import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;


/**
 * @author lc
 * @version 1.0
 * @date 2021/12/27 15:33
 */

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

/**
     * 发现如果继承了WebMvcConfigurationSupport,则在yml中配置的相关内容会失效。 需要重新指定静态资源
     *
     * @param registry
     */

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations(
                "classpath:/static/");
        registry.addResourceHandler("doc.html").addResourceLocations(
                "classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations(
                "classpath:/META-INF/resources/webjars/");
        super.addResourceHandlers(registry);
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //设置允许跨域的路径
        registry.addMapping("/**")
                //设置允许跨域请求的域名
                //   .allowedOrigins("*")
                .allowedOriginPatterns("*")
                //这里:是否允许证书 不再默认开启
                .allowCredentials(true)
                //设置允许的方法
                .allowedMethods("*")
                //跨域允许时间
                .maxAge(3600);
    }
}



http://localhost:你服务器端口/doc.html

注意,加上这个类后可能会影响拦截器的使用,
这个时候假如发现拦截器没有起作用,那可能是因为:有配置类继承了WebMvcConfigurationSupport(比如使用swagger的时候配置了),查询WebMvcConfigurationSupport源码发现其中有拦截器注册方法addInterceptors(InterceptorRegistry registry),所以在版本控制配置类中重写此方法添加拦截器,拦截器生效,问题解决。代码如下:

@Configuration
public class ApiConfig extends WebMvcConfigurationSupport {
	
	// 你自定义的拦截器类
	@Autowired
	private RequestParamInfoIntorceptor requestParamInfoIntorceptor;
	
	@Override
	protected void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(this.requestParamInfoIntorceptor).addPathPatterns("/**").excludePathPatterns("/luser/login", "/luser/register", "/send/message");
		super.addInterceptors(registry);
	}
	
}

4.注解介绍

@Api(tags = “”):接口分组
@ApiOperation(value = “”):接口名称
@ApiImplicitParam(name = “id”,value = “用户id”,required = true):接口参数声明
// 提供了过滤和包含参数的注解,可以排除或包含必须参数来简洁文档(用在实体类上)。
@ApiOperationSupport(ignoreParameters = {"id","orderDate.id"})
@ApiOperationSupport(order = 40,includeParameters = {"ignoreLabels","longUser.ids"})



在这里插入图片描述

@ApiResponses:

在 Rest 接口上使用,用作返回值的描述在这里插入图片描述

@ApiResponses(value = {
            @ApiResponse(code = 200, message = "接口返回成功状态"),
            @ApiResponse(code = 500, message = "接口返回未知错误,请联系开发人员调试")
    })
    @PostMapping("hello")
    public Results<UserVO> hello(@RequestBody UserVO userVO){

        Results<UserVO> results = new Results<>(200,"SUCCESS", userVO);
        return results;
    }

@ApiOperation:

用在方法上,说明方法的作用,每一个url资源的定义
在这里插入图片描述

@ApiOperation(value = "Hello 测试接口", notes = "访问此接口,返回hello语句,测试接口")
    @PostMapping("hello")
    public Results<UserVO> hello(@RequestBody UserVO userVO){

        Results<UserVO> results = new Results<>(200,"SUCCESS", userVO);
        return results;
    }

@PathVariable:

是获取get方式,url后面参数,进行参数绑定(单个参数或两个以内参数使用)

在这里插入图片描述


@ApiResponses(value = {
            @ApiResponse(code = 200, message = "接口返回成功状态"),
            @ApiResponse(code = 500, message = "接口返回未知错误,请联系开发人员调试")
    })
    @ApiOperation(value = "获取用户信息", notes = "访问此接口,返回用户信息")
    @PostMapping("/getUser/{id}")
    public String getUser(@PathVariable String id) throws InterruptedException {
        // 业务...
        return "";
    }

@RequestBody :
在当前对象获取整个http请求的body里面的所有数据(两个以上参数封装成对象使用)
在这里插入图片描述


@ApiResponses(value = {
            @ApiResponse(code = 200, message = "接口返回成功状态"),
            @ApiResponse(code = 500, message = "接口返回未知错误,请联系开发人员调试")
    })
    @ApiOperation(value = "Hello 测试接口", notes = "访问此接口,返回hello语句,测试接口")
    @PostMapping("hello")
    public Results<UserVO> hello(@RequestBody UserVO userVO){
        Results<UserVO> results = new Results<>(200,"SUCCESS", userVO);
        return results;
    }

paramType 的使用

@ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "项目ID", dataType = "String", paramType = "query", required = true),
        @ApiImplicitParam(name = "useridlist", value = "用户ID数组", dataType = "String", paramType = "body", allowMultiple = true, required = true ),
        @ApiImplicitParam(name = "Authorization", value = "身份验证Token", dataType = "String", paramType = "header"),
})

allowMultiple=true————表示是数组格式的参数
dataType=“body”————表示数组中参数的类型

dataType=“String” 代表请求参数类型为String类型,当然也可以是Map、User、int等;
paramType=“body” 代表参数应该放在请求的什么地方:

header-->放在请求头。请求参数的获取:@RequestHeader(代码中接收注解)
query -->用于get请求的参数拼接。请求参数的获取:@RequestParam(代码中接收注解)
path  -->(用于restful接口)-->请求参数的获取:@PathVariable(代码中接收注解)
body  -->放在请求体。请求参数的获取:@RequestBody(代码中接收注解)
form  -->(不常用)

在这里插入图片描述
在这里插入图片描述

对于入参是实体类的

@ApiMode + @ApiModelProperty

@ApiModelProperty(value = "商户id-userID", dataType = "String", required = true,example = "123456")

package com.zykj.newsell.pojo.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.Date;

/**
 * 营收统计接口的入参
 *
 * @author lc
 * @version 1.0
 * @date 2022/4/15 11:23
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "RevenueDto", description = "营收dto")
public class RevenueDto {
    @ApiModelProperty(value = "商户id-userID", dataType = "String", required = true, example = "123456")
    private String currentUserId; // 商户id-userID
	
	// 注意时间的入参格式 2022-04-15 08:45:00   需要补0,还要配置LocalDateTime 的格式,查看我的文章
    @ApiModelProperty(value = "开始时间", required = true, example = "2022-10-10 11:11:11")
    @JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
    private LocalDateTime  dateStart; // 开始时间

    @ApiModelProperty(value = "结束时间", required = true, example = "2022-10-10 11:11:11")
    @JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
    private LocalDateTime  dateEnd; // 结束时间

}


5.拓展

5.1 springsecurity整合knife4j(swagger)

首先,先按照上面的操作把knife4j整合进springboot项目,但是由于项目整合了springsecurity,会把knife4j的接口拦截掉。
解决方法:在springsecurity的配置类中,添加不拦截的路径

在这里插入图片描述

import com.zykj.zycx.filter.JwtAuthenticationTokenFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * security的配置类
 *
 * @author lc
 * @version 1.0
 * @date 2022/3/14 16:09
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class securityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    private AccessDeniedHandler accessDeniedHandler;

    // 替换掉默认的密码加密器
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // AuthenticationManager注入到容器
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/user/login", "/doc.html/**", "/swagger-ui.html/**", "/webjars/**",
                        "/v2/api-docs",//swagger api json
                        "/swagger-resources/configuration/ui",//用来获取支持的动作
                        "/swagger-resources",//用来获取api-docs的URI
                        "/swagger-resources/configuration/security",//安全选项
                        "/swagger-ui.html").anonymous()
                .anyRequest().authenticated();

        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        //配置异常处理器
        http.exceptionHandling()
                //配置认证失败处理器
                .authenticationEntryPoint(authenticationEntryPoint)
                .accessDeniedHandler(accessDeniedHandler);
        //允许跨域
        http.cors();
    }
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LC超人在良家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值