Springboot项目集成Swagger

本文介绍了如何在SpringBoot项目中集成Swagger和Knife4j,用于生成和管理API文档。首先,需要引入Knife4j的Maven依赖,并配置静态资源映射,确保文档页面可访问。接着,在WebMvcConfig中启用Swagger和Knife4j,并配置Swagger的Docket,包括文档信息和接口扫描规则。最后,通过注解如@Api,@ApiOperation等,详细描述接口、模型和参数,提高接口文档的可读性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
官网:https://swagger.io


一、准备工作

1). 导入knife4j的maven坐标

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

2). 设置静态资源映射

由于Swagger生成的在线文档中,涉及到很多静态资源,这些静态资源需要添加静态资源映射,否则接口文档页面无法访问。因此需要在 WebMvcConfig类中的addResourceHandlers方法中增加如下配置。

registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");

3). 在LoginCheckFilter中设置不需要处理的请求路径
需要将Swagger及Knife4j相关的静态资源直接放行,无需登录即可访问,否则我们就需要登录之后,才可以访问接口文档的页面。

在原有的不需要处理的请求路径中,再增加如下链接:

"/doc.html",
"/webjars/**",
"/swagger-resources",
"/v2/api-docs"

4).开启Swagger和Knife4j的功能。
这里我们就不需要再创建一个新的配置类了,我们直接在WebMvcConfig配置类中声明即可。

在该配置类中加上两个注解 @EnableSwagger2 @EnableKnife4j ,开启Swagger和Knife4j的功能。

@Slf4j
@Configuration
@EnableSwagger2  //开启Swagger功能
@EnableKnife4j   //开启Knife4j功能
public class WebMvcConfig extends WebMvcConfigurationSupport {


}

5). 查看接口文档

在这里插入图片描述


二、配置Swagger文档信息

1). Docket实例来配置Swaggger
Swagger实例Bean是Docket,所以通过配置Docket实例来配置Swaggger。

在配置类中声明一个Docket类型的bean, 通过该bean来指定生成文档的信息。

@Slf4j
@Configuration
@EnableSwagger2
@EnableKnife4j
public class WebMvcConfig extends WebMvcConfigurationSupport {
    //其他代码略
		
		
    @Bean
    public Docket createRestApi() {
        // 文档类型
        return new Docket(DocumentationType.SWAGGER_2);
    }
}

2). 查看接口文档
在这里插入图片描述

3).通过apiInfo()属性配置文档信息

    @Bean
    public Docket createRestApi() {
        //配置文档信息
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("瑞吉外卖")
                .version("1.0")
                .description("瑞吉外卖接口文档")
                .build();
        
        // 文档类型                                 //Docket 实例关联上 apiInfo()
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo);
    }

在这里插入图片描述


三、配置Swagger配置扫描接口

1). 通过select()方法,配置扫描接口方式

    @Bean
    public Docket createRestApi() {

        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("瑞吉外卖")
                .version("1.0")
                .description("瑞吉外卖接口文档")
                .build();

        // 文档类型
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo)
                // 通过.select()方法,去配置扫描接口
                .select()
                //RequestHandlerSelectors配置如何扫描接口
                .apis(RequestHandlerSelectors.basePackage("com.itheima.reggie.web"))
                .build();
    }

2). select()方法,其他方式扫描接口

any() // 扫描所有,项目中的所有接口都会被扫描到 
none() // 不扫描接口 
// 通过方法上的注解扫描,如:withMethodAnnotation(PostMapping.class)只扫描post请求
withMethodAnnotation(final Class<? extends Annotation> annotation) 
// 通过类上的注解扫描,如:withClassAnnotation(Controller.class)只扫描有controller注解的类中的接口 
​​​​​​​withClassAnnotation(final Class<? extends Annotation> annotation) 
// 根据包路径扫描接口
basePackage(final String basePackage) 

3). paths()方法,配置接口扫描过滤

any() // 任何请求都扫描 none() // 任何请求都不扫描 
regex(final String pathRegex) // 通过正则表达式控制 
ant(final String antPattern) // 通过ant()控制
    @Bean
    public Docket createRestApi() {

        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("瑞吉外卖")
                .version("1.0")
                .description("瑞吉外卖接口文档")
                .build();

        // 文档类型
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo)
                // 通过.select()方法,去配置扫描接口
                .select()
                //RequestHandlerSelectors配置如何扫描接口
                .apis(RequestHandlerSelectors.basePackage("com.itheima.reggie.web"))
                //配置接口扫描过滤,只扫描请求以/dish开头的接口
                .paths(PathSelectors.ant("/dish/**"))
                .build();
    }

在这里插入图片描述

三、常用注解

直接访问Knife4j的接口文档页面,可以查看到所有的接口文档信息,但是我们发现,这些接口文档分类及接口描述都是Controller的类名(驼峰命名转换而来)及方法名,而且在接口文档中,所有的请求参数,响应数据,都没有中文的描述,并不知道里面参数的含义,接口文档的可读性很差。
在这里插入图片描述

注解介绍

为了解决上述的问题,Swagger提供了很多的注解,通过这些注解,我们可以更好更清晰的描述我们的接口,包含接口的请求参数、响应数据、数据模型等。核心的注解,主要包含以下几个:

注解位置说明
@Api加载Controller类上,表示对类的说明
@ApiModel类(通常是实体类)描述实体类的作用
@ApiModelProperty属性描述实体类的属性
@ApiOperation方法说明方法的用途、作用
@ApiImplicitParams方法表示一组参数说明
@ApiImplicitParam方法用在@ApiImplicitParams注解中,指定一个请求参数的各个方面的属性

注解测试

实体类

可以通过 @ApiModel , @ApiModelProperty 来描述实体类及属性

@Data
@ApiModel("套餐")
public class Setmeal implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("主键")
    private Long id;
    
    //分类id
    @ApiModelProperty("分类id")
    private Long categoryId;
    
    //套餐名称
    @ApiModelProperty("套餐名称")
    private String name;

    //套餐价格
    @ApiModelProperty("套餐价格")
    private BigDecimal price;

    //状态 0:停用 1:启用
    @ApiModelProperty("状态")
    private Integer status;

    //编码
    @ApiModelProperty("套餐编号")
    private String code;

    //描述信息
    @ApiModelProperty("描述信息")
    private String description;

    //图片
    @ApiModelProperty("图片")
    private String image;

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    @TableField(fill = FieldFill.INSERT)
    private Long createUser;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;
}

响应实体R

@Data
@ApiModel("返回结果")
public class R<T> implements Serializable{

    @ApiModelProperty("编码")
    private Integer code; //编码:1成功,0和其它数字为失败

    @ApiModelProperty("错误信息")
    private String msg; //错误信息

    @ApiModelProperty("数据")
    private T data; //数据

    @ApiModelProperty("动态数据")
    private Map map = new HashMap(); //动态数据
	
	//省略静态方法 ....
}    

Controller类及其中的方法

描述Controller、方法及其方法参数,可以通过注解: @Api, @APIOperation, @ApiImplicitParams, @ApiImplicitParam

@RestController
@RequestMapping("/setmeal")
@Slf4j
@Api(tags = "套餐相关接口")
public class SetmealController {

    @Autowired
    private SetmealService setmealService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SetmealDishService setmealDishService;


    /**
     * 套餐分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    @ApiOperation(value = "套餐分页查询接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page",value = "页码",required = true),
            @ApiImplicitParam(name = "pageSize",value = "每页记录数",required = true),
            @ApiImplicitParam(name = "name",value = "套餐名称",required = false)
    })
    public R<Page> page(int page,int pageSize,String name){
        //分页构造器对象
        Page<Setmeal> pageInfo = new Page<>(page,pageSize);
        Page<SetmealDto> dtoPage = new Page<>();

        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        //添加查询条件,根据name进行like模糊查询
        queryWrapper.like(name != null,Setmeal::getName,name);
        //添加排序条件,根据更新时间降序排列
        queryWrapper.orderByDesc(Setmeal::getUpdateTime);

        setmealService.page(pageInfo,queryWrapper);

        //对象拷贝
        BeanUtils.copyProperties(pageInfo,dtoPage,"records");
        List<Setmeal> records = pageInfo.getRecords();

        List<SetmealDto> list = records.stream().map((item) -> {
            SetmealDto setmealDto = new SetmealDto();
            //对象拷贝
            BeanUtils.copyProperties(item,setmealDto);
            //分类id
            Long categoryId = item.getCategoryId();
            //根据分类id查询分类对象
            Category category = categoryService.getById(categoryId);
            if(category != null){
                //分类名称
                String categoryName = category.getName();
                setmealDto.setCategoryName(categoryName);
            }
            return setmealDto;
        }).collect(Collectors.toList());

        dtoPage.setRecords(list);
        return R.success(dtoPage);
    }

}

重启服务测试:展示修改了套餐模块分页查询的效果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

穿城大饼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值