后端整合Swagger+Knife4j
什么是接口文档
什么是接口文档?
写接口信息的文档,
每条接口包括:
- 请求参数
- 响应参数
- 错误码
- 接口地址
- 接口名称
- 请求类型
- 请求格式
- 备注
who 谁用?
一般是后端或者负责人来提供,后端和前端都要使用
为什么需要接口文档
为什么需要接口文档?
- 有个书面内容(背书或者归档),便于大家参考和查阅,便于 沉淀和维护 ,拒绝口口相传
- 接口文档便于前端和后端开发对接,前后端联调的 介质 。后端 => 接口文档 <= 前端
- 好的接口文档支持在线调试、在线测试,可以作为工具提高我们的开发测试效率
怎么做接口文档
怎么做接口文档?
- 手写(比如腾讯文档、Markdown 笔记)
- 自动化接口文档生成:自动根据项目代码生成完整的文档或在线调试的网页。
Swagger,Postman(侧重接口管理)(国外);
apifox、apipost、eolink(国产);
Swagger
Spring Boot整合swagger使用教程(这一篇就够了)_整合swagger怎么成功-CSDN博客
Swagger 原理:
- 引入依赖(Swagger 或 Knife4j:https://doc.xiaominfo.com/knife4j/documentation/get_start.html)
- 自定义 Swagger 配置类
- 定义需要生成接口文档的代码位置(Controller)
- 千万注意:线上环境不要把接口暴露出去!!!可以通过在 SwaggerConfig 配置文件开头加上 @Profile({“dev”, “test”}) 限定配置仅在部分环境开启
- 启动即可
- 可以通过在 controller 方法上添加 @Api、@ApiImplicitParam(name = “name”,value = “姓名”,required = true) @ApiOperation(value = “向客人问好”) 等注解来自定义生成的接口描述信息
如果 springboot version >= 2.6,需要添加如下配置:
spring:mvc:pathmatch:matching-strategy: ant_path_matcher
- 依赖引入
<!-- swagger 接口文档 --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency>
- config文件夹新建
SwaggerConfig文件
package com.yupi.usercenter.config;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.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;/*** @author: shayu* @date: 2022/11/20* @ClassName: yupao-backend01* @Description: 自定义 Swagger 接口文档的配置*/
@Configuration // 配置类
@EnableSwagger2 // 开启 swagger2 的自动配置
public class SwaggerConfig {@Beanpublic Docket docket() {// 创建一个 swagger 的 bean 实例return new Docket(DocumentationType.SWAGGER_2)// 配置接口信息.select() // 设置扫描接口// 配置如何扫描接口.apis(RequestHandlerSelectors//.any() // 扫描全部的接口,默认//.none() // 全部不扫描.basePackage("com.yupi.usercenter.controller") // 扫描指定包下的接口,最为常用//.withClassAnnotation(RestController.class) // 扫描带有指定注解的类下所有接口//.withMethodAnnotation(PostMapping.class) // 扫描带有只当注解的方法接口).paths(PathSelectors.any() // 满足条件的路径,该断言总为true//.none() // 不满足条件的路径,该断言总为false(可用于生成环境屏蔽 swagger)//.ant("/user/**") // 满足字符串表达式路径//.regex("") // 符合正则的路径).build();}// 基本信息设置private ApiInfo apiInfo() {Contact contact = new Contact("shayu", // 作者姓名"shayuyu.cn", // 作者网址"shayu-yusha@qq.com"); // 作者邮箱return new ApiInfoBuilder().title("鱼泡伙伴匹配系统-接口文档") // 标题.description("众里寻他千百度,慕然回首那人却在灯火阑珊处") // 描述.termsOfServiceUrl("https://www.baidu.com") // 跳转连接.version("1.0") // 版本.license("Swagger-的使用(详细教程)").licenseUrl("https://blog.csdn.net/xhmico/article/details/125353535").contact(contact).build();}}
- 加上yml配置
- 访问
太丑了,选用下面这个方法
Knife4j
Knife4j是一个集Swagger2 和 OpenAPI3
为一体的增强解决方案
springboot集成knife4j详细教程_springboot整合knife4j-CSDN博客
- 依赖引入
<!-- knife4j 接口文档 --><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>2.0.7</version></dependency>
- 新建SwaggerConfig文件
package com.yupi.usercenter.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
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.EnableSwagger2WebMvc;/*** @author: shayu* @date: 2022/11/20* @ClassName: yupao-backend01* @Description: 自定义 Swagger 接口文档的配置*/
@Configuration
@EnableSwagger2WebMvc
@Profile({"dev", "test"}) //版本控制访问
public class SwaggerConfig {@Bean(value = "defaultApi2")public Docket defaultApi2() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()// 这里一定要标注你控制器的位置.apis(RequestHandlerSelectors.basePackage("com.yupi.usercenter.controller")).paths(PathSelectors.any()).build();}/*** api 信息* @return*/private ApiInfo apiInfo() {return new ApiInfoBuilder().title("鱼皮用户中心").description("鱼皮用户中心接口文档").termsOfServiceUrl("https://github.com/liyupi").contact(new Contact("shayu","https://shayuyu.cn/","shayu-yusha@qq.com")).version("1.0").build();}
}
- 配置yml
就上面说到的配置cv过来就行 - 柚见用户管理系统接口文档
注意:
补充一下,一定要注意运行环境和扫描的controller包的路径
可以通过在 controller 方法上添加 @Api、@ApiImplicitParam(name = “name”,value = “姓名”,required = true) @ApiOperation(value = “向客人问好”) 等注解来自定义生成的接口描述信息。
防止接口信息暴露
千万注意:线上环境不要把接口暴露出去!!!
可以通过在 SwaggerConfig 配置文件开头加上 @Profile({“dev”, “test”}) 限定配置仅在部分环境开启
爬虫- 存量用户信息导入及同步
- 把所有星球用户的信息导入
- 把写了自我介绍的同学的标签信息导入
- Fehelper前端辅助插件,推荐安装
看上了网页信息,怎么抓到?
- 分析原网站是怎么获取到这些数据的,哪个接口?
按F12打开控制台,查看网咯请求,复制url代码便于查看和执行
curl "https://api.zsxq.com/v2/hashtags/48844541281228/topics?count=20" ^-H "authority: api.zsxq.com" ^-H "accept: application/json, text/plain, */*" ^-H "accept-language: zh-CN,zh;q=0.9" ^-H "cache-control: no-cache" ^-H "origin: https://wx.zsxq.com" ^-H "pragma: no-cache" ^-H "referer: https://wx.zsxq.com/" ^--compressed
-
用程序去调用接口(java okhttp httpclient / python 都可以)
-
处理(清洗)一下数据,之后就可以写到数据库里
流程
-
从 excel 中导入全量用户数据,判重 。
EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel (alibaba.com) -
抓取写了自我介绍的同学信息,提取出用户昵称、用户唯一 id、自我介绍信息
-
从自我介绍中提取信息,然后写入到数据库中
两种读对象的方式:
- 确定表头:建立对象,和表头形成映射关系
- 不确定表头:每一行数据映射为 Map<String, Object>
两种读取模式:
- 监听器:先创建监听器、在读取文件时绑定监听器。单独抽离处理逻辑,代码清晰易于维护;一条一条处理,适用于数据量大的场景。
- 同步读:无需创建监听器,一次性获取完整数据。方便简单,但是数据量大时会有等待时常,也可能内存溢出。
easy excel
easy Excel引入依赖。进入官网Get Started就可以了。(官方文档简单好用,跟着走就可以了。)
https://alibaba-easyexcel.github.io/index.html
- 引入依赖
<!-- easy Excel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.0</version></dependency>
- 新建文件夹和星球表格
用户信息文件
package com.yupi.usercenter.easyExcel;import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;/*** @author: shayu* @date: 2022/11/20* @ClassName: yupao-backend01* @Description: 星球表格用户信息*/
@Data
public class XingQiuTableUserInfo {/*** id*/@ExcelProperty("成员编号")private String planetCode;/*** 用户昵称*/@ExcelProperty("成员昵称")private String username;}
- 新建监听器
package com.yupi.usercenter.easyExcel;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import lombok.extern.slf4j.Slf4j;// 有个很重要的点 TableListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
@Slf4j
public class TableListener implements ReadListener<XingQiuTableUserInfo> {/*** 这个每一条数据解析都会来调用** @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}* @param context*/@Overridepublic void invoke(XingQiuTableUserInfo data, AnalysisContext context) {System.out.println(data);}/*** 所有数据解析完成了 都会来调用** @param context*/@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {System.out.println("已解析完成");}}
- 新建读取文件
package com.yupi.usercenter.easyExcel;import com.alibaba.excel.EasyExcel;import java.util.List;/*** @author: shayu* @date: 2022/11/20* @ClassName: yupao-backend01* @Description: 导入Excel,读取数据*/
public class ImportExcel {/*** 读取数据*/public static void main(String[] args) {// 写法1:JDK8+ ,不用额外写一个DemoDataListener// since: 3.0.0-beta1//Excel数据文件放在自己电脑上,能够找到的路径String fileName = "C:\\Users\\25073\\Desktop\\testExcel.xlsx";
// readByListener(fileName);synchronousRead(fileName);}/*** 监听器读取* @param fileName*/public static void readByListener(String fileName) {// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭// 这里每次会读取100条数据 然后返回过来 直接调用使用数据就行EasyExcel.read(fileName, XingQiuTableUserInfo.class, new TableListener()).sheet().doRead();}/*** 同步读* 同步的返回,不推荐使用,如果数据量大会把数据放到内存里面*/public static void synchronousRead(String fileName) {// 这里 需要指定读用哪个class去读,然后读取第一个sheet 同步读取会自动finishList<XingQiuTableUserInfo> list = EasyExcel.read(fileName).head(XingQiuTableUserInfo.class).sheet().doReadSync();for (XingQiuTableUserInfo xingQiuTableUserInfo : list) {System.out.println(xingQiuTableUserInfo);}}
}
package com.yupi.usercenter.easyExcel;import com.alibaba.excel.EasyExcel;
import org.apache.commons.lang3.StringUtils;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;/*** 导入星球用户到数据库*/
public class ImportXingQiuUser {public static void main(String[] args) {//Excel数据文件放在自己电脑上,能够找到的路径String fileName = "C:\\Users\\25073\\Desktop\\testExcel.xlsx";// 这里 需要指定读用哪个class去读,然后读取第一个sheet 同步读取会自动finishList<XingQiuTableUserInfo> userInfoList =EasyExcel.read(fileName).head(XingQiuTableUserInfo.class).sheet().doReadSync();System.out.println("总数 = " + userInfoList.size());Map<String, List<XingQiuTableUserInfo>> listMap =userInfoList.stream().filter(userInfo -> StringUtils.isNotEmpty(userInfo.getUsername())).collect(Collectors.groupingBy(XingQiuTableUserInfo::getUsername));for (Map.Entry<String, List<XingQiuTableUserInfo>> stringListEntry : listMap.entrySet()) {if (stringListEntry.getValue().size() > 1) {System.out.println("username = " + stringListEntry.getKey());System.out.println("1");}}System.out.println("不重复昵称数 = " + listMap.keySet().size());}
}
比较麻烦,放弃了