SpringDoc【使用詳解】

SpringDoc使用詳解

  • 一、何為SpringDoc
  • 二、概念解釋
  • 三、SpringDoc使用
    • 2.1簡單集成
    • 2.2 配置SpringDoc
      • 2.2.1 yml方式配置
      • 2.2.2配置文檔信息
    • 2.3配置文檔分組
    • 2.4使用注解
      • 2.4.1 @Tag
      • 2.4.2 @Operation
      • 2.4.3 @Schema
      • 2.4.4 @NotNull
      • 2.4.5 @Parameter
      • 2.4.6 @Parameters
      • 2.4.7 @ApiResponses 和@ApiResponse
  • 四、認證授權
    • 3.1無需認證
    • 3.2需要認證
  • 五、SpringDoc整合Knife4j
    • 1.前世今生
    • 2.Spring Boot版本兼容性
    • 3.Spring Boot 3
    • 4.Spring Boot 2

一、何為SpringDoc

SpringDoc是一個用來自動生成API文檔的庫。它是基于SpringBoot項目的,遵循OpenAPI3(一個組織規定的規范)規范。它是通過檢查我們運行中的程序,推斷出基于Spring配置、類結構和各種注解的API語義,從而自動生成JSON、YAML和HTML格式的接口文檔。
而我們不得不提的就是Swagger。Swagger是一個公司的開源項目,將自己的API設計貢獻給了OpenAPI并由其標準化。在SpringDoc之前我們還可以使用Springfox,和SpringDoc一樣是一個用于生成API文檔的庫,2020年起不再更新。
SpringDoc官網

二、概念解釋

談到API文檔,那就繞不開大名鼎鼎的Swagger,但是你是否還聽說過:OpenAPI,Springfox,Springdoc?你第一次看到這些腦瓜子是不是嗡嗡的?

  • OpenAPI
    是一個組織(OpenAPI Initiative),他們指定了一個如何描述HTTP API的規范(OpenAPI Specification)。既然是規范,那么誰想實現都可以,只要符合規范即可。

  • Swagger
    它是SmartBear這個公司的一個開源項目,里面提供了一系列工具,包括著名的 swagger-ui。swagger是早于OpenApi的,某一天swagger將自己的API設計貢獻給了OpenApi,然后由其標準化了。

  • Springfox
    是Spring生態的一個開源庫,是Swagger與OpenApi規范的具體實現。我們使用它就可以在spring中生成API文檔。以前基本上是行業標準,目前最新版本可以支持 Swagger2, Swagger3 以及 OpenAPI3 三種格式。但是其從 2020年7月14號就不再更新了,不支持springboot3,所以業界都在不斷的轉向我們今天要談論的另一個庫Springdoc,新項目就不要用了。

  • Springdoc
    算是后起之秀,帶著繼任Springfox的使命而來。其支持OpenApi規范,支持Springboot3,我們的新項目都應該使用這個。

三、SpringDoc使用

我們可以在springboot中使用SpringDoc來生成API文檔,詳情可以參考官網,下面我們來簡單的實踐一下。

2.1簡單集成

在springboot中使用springdoc起步非常容易,只需要引入其starter即可

<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.8.6</version></dependency>

運行后訪問下面的鏈接即可

http://server:port/context-path/swagger-ui.html

例如

http://localhost:8080/swagger-ui.html

例如我們有如下代碼:

@RestController
@RequestMapping("/api/programmer")
public class ProgrammerController {@PostMapping()public Programmer createProgrammer(@RequestBody CreateProgrammerRequest request) {return new Programmer(1, request.getAge(), request.getProgrammingLang());}@GetMapping("/{id}")public Programmer getProgrammer(@PathVariable Integer id) {return new Programmer(1, 35, List.of("Java,Python,SQL"));}
}

添加依賴運行后訪問http://localhost:8080/swagger-ui.html后結果如下
在這里插入圖片描述
是不是特牛逼?當然springdoc的集成不可能就這點東西,不然也沒有這篇文章了,咱接著往下看。苦于網上的一些教程不直觀,對初學者不友好,所以本文以代碼和其效果的形式來展示,保你一看就會。

2.2 配置SpringDoc

2.2.1 yml方式配置

springdoc:api-docs:# 是否開啟接口文檔enabled: trueswagger-ui:# 持久化認證數據persistAuthorization: trueinfo:# 標題title: '標題:${demo.name}多租戶管理系統_接口文檔'# 描述description: '描述:用于管理集團旗下公司的人員信息,具體包括XXX,XXX模塊...'# 版本version: '版本號: ${demo.version}'# 作者信息contact:name: Agazigiemail: 123456789@qq.comurl: www.baidu.comcomponents:# 鑒權方式配置security-schemes:apiKey:type: APIKEYin: HEADERname: ${sa-token.token-name}#這里定義了兩個分組,可定義多個,也可以不定義group-configs:- group: 1.演示模塊packages-to-scan: org.dromara.demo- group: 2.通用模塊packages-to-scan: org.dromara.web- group: 3.系統模塊packages-to-scan: org.dromara.system- group: 4.代碼生成模塊packages-to-scan: org.dromara.generator

在這里插入圖片描述

2.2.2配置文檔信息

得益于springboot的強大,我們只需添加一個依賴就可以使用API文檔了,但是使用的都是默認值,我們當然也希望對其進行各種自定義的配置

  • 配置文檔信息
    創建一個OpenAPI 的bean,配置文檔名稱等信息
@Configuration
public class SpringDocConfig {@Beanpublic OpenAPI myOpenAPI() {return new OpenAPI().info(new Info() //設置信息.title("程序員API") //標題.description("程序員的大本營") //描述信息.version("v1.0.0")  //版本.license(new License() //許可證.name("許可協議").url("https://shusheng007.top")).contact(new Contact() //作者信息.name("書生007").email("wangben850115@gmail.com"))).externalDocs(new ExternalDocumentation() //外部文檔.description("ShuSheng007博客").url("https://shusheng007.top"));}// 指定掃描的包路徑@Beanpublic GroupedOpenApi publicApi() {return GroupedOpenApi.builder().group("my_api") // 分組名稱(自定義).packagesToScan("com.ls.ai.demo.controller") // 包路徑.addOpenApiMethodFilter(methodPredicate()) // 方法級注解過濾.build();}// 定義過濾條件:僅包含帶有 @Operation 注解的方法private Predicate<HandlerMethod> methodPredicate() {return handlerMethod ->handlerMethod.hasMethodAnnotation(io.swagger.v3.oas.annotations.Operation.class);}// 可選:過濾類級別的注解(如 @Tag)private Predicate<HandlerMethod> classPredicate() {return handlerMethod ->handlerMethod.getBeanType().isAnnotationPresent(io.swagger.v3.oas.annotations.tags.Tag.class);}}

效果:
在這里插入圖片描述
里面的配置項很多,可以根據代碼和截圖對照一下,按照自己的需求配置即可

2.3配置文檔分組

用來配置分組的,假如你有兩類controller一類以/api為前綴,一類以/admin為前綴,就可以將其配置為兩個分組。很多時候我們只有一個分組,所以就不需要下面的配置。

@Configuration
public class SpringDocConfig {...@Beanpublic GroupedOpenApi publicApi() {return GroupedOpenApi.builder().group("api").pathsToMatch("/api/**").build();}@Beanpublic GroupedOpenApi adminApi() {return GroupedOpenApi.builder().group("admin").pathsToMatch("/admin/**").build();}
}

效果:
在這里插入圖片描述
可以通過右上角的下拉框選擇要展示的group。

2.4使用注解

這個是咱們的重頭戲,OpenApi規范提供了很多注解,下面是一些常用的

注解含義
@Tag用在controller類上,描述此controller的信息
@Operation用在controller的方法里,描述此api的信息
@Parameter用在controller方法里的參數上,描述參數信息
@Parameters用在controller方法里的參數上
@Schema用于Entity,以及Entity的屬性上
@ApiResponse用在controller方法的返回值上
@ApiResponses用在controller方法的返回值上
@Hidden用在各種地方,用于隱藏其api

下面我們一起來看看效果

2.4.1 @Tag

@Tag(name = "程序員", description = "程序員樂園")
@RestController
@RequestMapping("/api/programmer")
public class ProgrammerController {
...
}

效果
在這里插入圖片描述

2.4.2 @Operation

@Operation(summary = "創建程序員", description = "用于創建一個悶騷的程序員")
@PostMapping()
public Programmer createProgrammer(@RequestBody CreateProgrammerRequest request) {return new Programmer(666, "王二狗", request.getAge(), request.getProgrammingLang());
}

在這里插入圖片描述
@Operation 其實很復雜的,我們可以將下面要用的@Parameter以及@ApiResponse都可以配置在它里面。

2.4.3 @Schema

@Schema 用于實體類和其屬性,例如有如下代碼:

@Schema(description = "創建程序員入參")
public class CreateProgrammerRequest {@Schema(description = "名稱", example = "王二狗")private String name;@Schema(description = "年齡", example = "35")private Integer age;@Schema(description = "掌握的編程語言", type = "List", example = "[\"Java\",\"Sql\"]")private List<String> programmingLang;
}

效果:
在這里插入圖片描述
還可以切換到 Schema選項進行查看
在這里插入圖片描述

2.4.4 @NotNull

同時,Springdoc還支持 Java Bean Validation API 的注解,例如@NotNull

@Schema(description = "創建程序員入參")
public class CreateProgrammerRequest {@NotNull@Schema(description = "名稱", example = "王二狗")private String name;@NotNull@Min(18)@Max(35)@Schema(description = "年齡", example = "35")private Integer age;...
}

效果:
在這里插入圖片描述
注意紅框中的內容,name和age右上角都有出現了一個紅色的星星,表示是必填的。age也被限制了范圍。

2.4.5 @Parameter

用于添加接口參數信息

@GetMapping("/{id}")
public Programmer getProgrammer(@Parameter(description = "程序員id") @PathVariable Integer id) {...
}

效果
在這里插入圖片描述

2.4.6 @Parameters

@Parameter作用一樣,但是可以批量添加,不用一個一個的寫在參數前面

@Parameters(value = {@Parameter(name = "name", description = "姓名", in = ParameterIn.PATH),@Parameter(name = "age", description = "年齡", in = ParameterIn.QUERY)
})
@GetMapping("/{name}")
public List<Programmer> getProgrammers(@PathVariable("name") String name, @RequestParam("age") Integer age) { ...
}

parameters里的parameter使用name來找到方法中的入參,這塊要對應上。

效果:

在這里插入圖片描述

2.4.7 @ApiResponses 和@ApiResponse

顧名思義,此注解用來描述返回值的。

@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "成功",content = {@Content(mediaType = "application/json",schema = @Schema(implementation = Programmer.class))}),@ApiResponse(responseCode = "405", description = "非法輸入",content = @Content)})@PostMapping()public Programmer createProgrammer(@RequestBody CreateProgrammerRequest request) {...}

效果
在這里插入圖片描述
可見,我們成功配置了兩種情況的返回值。但是我們一般不會手動給每個API 寫上一堆@ApiResponse,那的多煩啊。業界通常會有一個統一的返回類型,例如

public class Result<T> implements Serializable {private int code;private String message;private T data;private String traceId;
}

還會有一個統一的異常處理類,使用@RestControllerAdvice標記,然后每個方法會捕捉對應的異常,只要我們使用@ResponseStatus來標記這些方法,springdoc就會自動生成相應的文檔

@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(value = Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public Result handleException(HttpServletRequest httpServletRequest, Exception e) {return new Result(StatusCode.FAILED.getCode(), StatusCode.FAILED.getMessage(), null);}@ExceptionHandler(value = ApiException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public Result handleBusinessException(HttpServletRequest httpServletRequest, ApiException e) {return new Result(e.getCode(), e.getMessage(), null);}
}

例如我們有如下代碼:

...
@RequestMapping(value = "/api/programmer",produces =  "application/json")
public class ProgrammerController {@GetMapping("/{id}")public Result<Programmer> getProgrammer(@Parameter(description = "程序員id") @PathVariable Integer id) {...}
}

生成的api文檔如下:

在這里插入圖片描述
可見,多了400和500。

四、認證授權

我們知道·swagger-ui·不僅可以看API文檔也可以直接調用API,這點很牛逼。但有時我們的服務需要認證,否則就調用不通,那怎么辦?稍安勿躁,OpenApi規范也考慮到了這個問題。

OpenAPI 3.0 支持下面的認證模式:

  • HTTP authentication schemes (使用Authorization header):
  • Basic
  • Bearer
  • Other HTTP schemes as defined by RFC 7235 and HTTP Authentication Scheme Registry
  • API keys in headers, query string or cookies
  • Cookie authentication
  • OAuth 2
  • OpenID Connect Discovery
    有的我也沒用過,我們常用的就是Http Auth,以及OAuth2。本文以HTTP Bearer來作為我們服務的認證授權模式,如下圖所示。
    在這里插入圖片描述

3.1無需認證

當你的服務沒有認證機制的話是可以直接調用的:

每個API 右上角都有一個try it out按鈕,點擊輸入參數點擊execute按鈕即可,如下所示。
在這里插入圖片描述

3.2需要認證

如果你的服務需要認證后才能調用,那么默認情況下就不行了。例如你使用了Spring Security,或者你自己寫了個Filter 來實現認證功能。

下面是demo服務用來做認證的Filter,采用HTTP Bearer 模式。所以需要在請求的Authentication Header 里 攜帶token 123才能通過認證。

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {...@Overrideprotected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException {...// get token from header [Authorization: Bearer <token>]String authHeader = request.getHeader(AUTH_HEADER);...String authToken = authHeader.split(" ")[1];if (!"123".equals(authToken)) {genUnauthResponse(response);return;}filterChain.doFilter(request, response);}

所以當從swagger-ui上調用API時,返回了401,如下圖所示。那怎么才能正常調用API呢?接下來讓我們看一下
在這里插入圖片描述

Springdoc 使用@SecurityScheme 來定義一個安全模式,我們可以定義全局的,也可以針對某個controller定義類級別的,我們這里定義一個全局的。

  1. 在Application類上添加@SecurityScheme
@SecurityScheme(name = "api_token", type = SecuritySchemeType.HTTP, scheme ="bearer", in = SecuritySchemeIn.HEADER)
@SpringBootApplication
public class SpringdocIntegrateApplication {public static void main(String[] args) {SpringApplication.run(SpringdocIntegrateApplication.class, args);}
}

我們定義了一個名為api_token的安全模式,并指定了其使用HTTP Bearer的方式。

  1. 使此安全模式生效
@Configuration
public class SpringDocConfig {@Beanpublic OpenAPI myOpenAPI() {return new OpenAPI()....security(List.of(new SecurityRequirement().addList("api_token")));}
}

注意api_token正是我們第一步定義的那個Security schema。

經過上面兩步后查看生成的API文檔,你會發現其右上角出現了一個Authorize的按鈕, 而且每個API的右邊也出現了一把小鎖,如下圖所示。
在這里插入圖片描述
當點擊Authorize按鈕后會彈出一個讓你提供認證信息的彈出,其根據不同的認證方式會有所區別。

在這里插入圖片描述
我們這里需要輸入一個token,然后點擊Authorize按鈕后關閉此彈窗。你會發現每個API右邊的那把小鎖從打開狀態變為了關閉狀態,顏色也從灰色變成了黑色,證明其生效了。

然后我們再來請求一下API,就會正常返回了。

  1. 聲明是否需要認證
    默認情況下按照上面兩步設置后,整個應用程序的API生效,但是有的API是不需要認證的,例如登錄。 對于這種情況,我們可以使用@SecurityRequirements()來設置。
@RestController
@RequestMapping(value = "/admin",produces =  "application/json")
public class AuthController {...@SecurityRequirements()@PostMapping("/login")public Result<String> login(@RequestBody LoginRequest request){return Result.ok("123");}
}

@SecurityRequirements() 里面需要一個String數組,里面列出需要使用的@SecurityScheme,例如我們這里的api_token。如果不寫就說明不需要任何的安全模式,這里就是這種情況。
在這里插入圖片描述
從上圖可以看出,/admin/login這個API右邊沒有小鎖的標志,表示其不需要認證。針對本案例來說,不需要認證的意思就是:在發起這個請求的時候,不在Authentication header里面附加token。

這里只是展示了HTTP bearer 這種安全模式,其他的原理類似,小朋友們可以開動你們聰明的大腦研究一下,給補充到這里。

五、SpringDoc整合Knife4j

1.前世今生

在更名為Knife4j之前,原來的名稱是叫swagger-bootstrap-ui,這是兩種不一樣風格的Ui,對比情況如下:

名稱開發語言&框架狀態最后版本風格
Knife4jJava、JavaScript、Vue持續更新中…黑色
swagger-bootstrap-uiJava、JavaScript、jQuery停更1.9.6藍色

Knife4j從開源至今,目前主要經歷版本的變化,分別如下:

版本說明
1.0~1.9.6名稱是叫swagger-bootstrap-ui,藍色風格Ui
1.9.6藍色皮膚風格,開始更名,增加更多后端模塊
2.0~2.0.5Ui基于Vue2.0+AntdV重寫,黑色風格,參考示例,底層依賴的springfox框架版本是2.9.2,僅提供Swagger2規范的適配
2.0.6~2.0.9底層springfox框架版本升級至2.10.5,僅提供Swagger2規范的適配
3.0~3.0.3底層依賴springfox框架版本升級至3.0.3,OpenAPI規范是v3,過度版本,建議開發者不要使用
4.0~區分OpenAPI2和Swagger3的Maven坐標artifactId
OpenAPI2規范服務端解析框架穩定在springfox2.10.5
OpenAPI3框架服務端解析跟隨springdoc項目更新迭代
建議開發者使用該版本,請參考4.x升級文檔

2.Spring Boot版本兼容性

首先,確保您了解您的項目所使用的Spring Boot版本。
以下是一些常見的Spring Boot版本及其對應的Knife4j版本兼容推薦:

Spring Boot版本Knife4j Swagger2規范Knife4j OpenAPI3規范
1.5.x~2.0.0<Knife4j 2.0.0>=Knife4j 4.0.0
2.0~2.2Knife4j 2.0.0 ~ 2.0.6>=Knife4j 4.0.0
2.2.x~2.4.0Knife4j 2.0.6 ~ 2.0.9>=Knife4j 4.0.0
2.4.0~2.7.x>=Knife4j 4.0.0>=Knife4j 4.0.0
>= 3.0>=Knife4j 4.0.0>=Knife4j 4.0.0

Knife4j在之前的版本更新中,逐漸提供了一些服務端適配的增強特性功能。

但是開發者應該明白,不管是Swagger2規范還是OpenAPI3規范,Knife4j的最新版本的純Ui版本,是可以適配Spring Boot所有版本的。

如果你不考慮使用Knife4j提供的服務端增強功能,引入Knife4j的純Ui版本沒有任何限制。只需要考慮不同的規范即可

3.Spring Boot 3

提示
Spring Boot 3 只支持OpenAPI3規范
Knife4j提供的starter已經引用springdoc-openapi的jar,開發者需注意避免jar包沖突
JDK版本必須 >= 17
詳細Demo請參考knife4j-spring-boot3-demo

首先,引用Knife4j的starter,Maven坐標如下:

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

其實現在就可以使用Knife4j了,暫不做其他配置,啟動項目,瀏覽器輸入http://localhost:8080/doc.html查看接口文檔
由于我們沒有進行任何的屬性配置,所以看到的頁面是knife4j的初始頁面
在這里插入圖片描述

引入之后,其余的配置,開發者即可完全參考springdoc-openapi的項目說明,Knife4j只提供了增強部分,如果要啟用Knife4j的增強功能,可以在配置文件中進行開啟

部分配置如下:

# springdoc-openapi項目配置
springdoc:swagger-ui:path: /swagger-ui.htmltags-sorter: alphaoperations-sorter: alphaapi-docs:path: /v3/api-docsgroup-configs:- group: 'default'paths-to-match: '/**'packages-to-scan: com.xiaominfo.knife4j.demo.web
# knife4j的增強配置,不需要增強可以不配
knife4j:enable: truesetting:language: zh_cn

Knife4j更多增強配置明細,請移步文檔進行查看

最后,使用OpenAPI3的規范注解,注釋各個Spring的REST接口,示例代碼如下:

@RestController
@RequestMapping("body")
@Tag(name = "body參數")
public class BodyController {@Operation(summary = "普通body請求")@PostMapping("/body")public ResponseEntity<FileResp> body(@RequestBody FileResp fileResp){return ResponseEntity.ok(fileResp);}@Operation(summary = "普通body請求+Param+Header+Path")@Parameters({@Parameter(name = "id",description = "文件id",in = ParameterIn.PATH),@Parameter(name = "token",description = "請求token",required = true,in = ParameterIn.HEADER),@Parameter(name = "name",description = "文件名稱",required = true,in=ParameterIn.QUERY)})@PostMapping("/bodyParamHeaderPath/{id}")public ResponseEntity<FileResp> bodyParamHeaderPath(@PathVariable("id") String id,@RequestHeader("token") String token, @RequestParam("name")String name,@RequestBody FileResp fileResp){fileResp.setName(fileResp.getName()+",receiveName:"+name+",token:"+token+",pathID:"+id);return ResponseEntity.ok(fileResp);}
}

最后,訪問Knife4j的文檔地址:http://ip:port/doc.html即可查看文檔

4.Spring Boot 2

提示
Spring Boot 版本建議 2.4.0~3.0.0之間
Spring Boot 版本 < 2.4 版本則建議選擇Knife4j 4.0之前的版本
Spring Boot 2 + OpenAPI2 demo:knife4j-spring-boot27-demo
Spring Boot 2 + OpenAPI3 demo:knife4j-springdoc-openapi-demo

OpenAPI2
OpenAPI2(Swagger)規范是Knife4j之前一直提供支持的版本,底層依賴框架為Springfox,此次在4.0版本開始

Knife4j有了新的變化,主要有以下幾點:

  • Springfox版本選擇的依然是2.10.5版本,而并非springfox最新3.0.0版本
  • 不支持以Springfox框架為基礎的OpenAPI3規范,放棄Springfox項目的后續版本適配支持工作
  • Spring Boot 版本建議 2.4.0~3.0.0之間
    可以使用 knife4j-openapi2-spring-boot-starter,maven 坐標如下:
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId><version>4.5.0</version>
</dependency>

配置yml屬性,如下:

knife4j:enable: trueopenapi:title: Knife4j官方文檔description: "`我是測試`,**你知道嗎**# aaa"email: xiaoymin@foxmail.comconcat: 八一菜刀url: https://docs.xiaominfo.comversion: v4.0license: Apache 2.0license-url: https://stackoverflow.com/terms-of-service-url: https://stackoverflow.com/group:test1:group-name: 分組名稱api-rule: packageapi-rule-resources:- com.knife4j.demo.new3

最后,訪問Knife4j的文檔地址:http://ip:port/doc.html即可查看文檔
OpenAPI3
OpenAPI3的規范,目前針對Java的Spring Boot項目,主要支持的有2個版本

  • springfox 3.0.0: 同時兼容OpenAPI2以及OpenAPI3,但是停更很久了
  • springdoc-openapi: 兼容OpenAPI3規范,更新速度頻繁
    Knife4j在只有的OpenAPI3規范中,底層基礎框架選擇springdoc-openapi項目

針對Springfox3.0.0版本會放棄。

建議開發者如果使用OpenAPI3規范的話,也盡快遷移過來。

可以使用 knife4j-openapi3-spring-boot-starter,maven 坐標如下:

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

引入jar包后,同上面的Spring Boot 3版本使用方式一樣,進行配置即可。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/77409.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/77409.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/77409.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PHP 阿里云oss 使用指南

1.介紹 把圖片放到阿里云上的空間上&#xff0c;可以使用cdn加速。 可以在程序里直接調用 要使用阿里云 oss sdk &#xff0c;請先到阿里云下載 或用 copmposer 安裝 相關鏈接&#xff1a; 安裝OSS PHP SDK_對象存儲(OSS)-阿里云幫助中心 composer require aliyuncs/oss…

【AI提示詞】常青筆記生成器

提示說明 生成適用于多個場景和領域的常青筆記&#xff0c;滿足“常青筆記”的核心特性和結構。 提示詞 # 角色: 常青筆記生成器## 角色簡介: - 作者: xxx - 版本號: 1.0 - 更新時間: xxx - 語言: 中文## 定位: - &#x1f3af; 生成適用于多個場景和領域的常青筆記&#x…

在 Lua 中,`for` 和 `while` 是兩種核心的循環結構的詳細用法

在 Lua 中&#xff0c;for 和 while 是兩種核心的循環結構&#xff0c;用于實現重復執行邏輯。以下是它們的詳細用法、進階技巧及注意事項&#xff1a; 在 Lua 中&#xff0c;for 和 while 是兩種核心的循環結構的詳細用法—目錄 一、for 循環1. 數值 for 循環基礎語法&#xf…

A2DP(Advanced Audio Distribution Profile)是藍牙協議棧中用于音頻傳輸的一個標準化協議

A2DP&#xff08;Advanced Audio Distribution Profile&#xff09;是藍牙協議棧中用于音頻傳輸的一個標準化協議&#xff0c;主要用于高質量音頻流的無線傳輸。以下是A2DP協議的詳細信息&#xff1a; 定義 A2DP協議允許音源設備&#xff08;Source&#xff0c;簡稱SRC&#…

STM32_USB

概述 本文是使用HAL庫的USB驅動 因為官方cubeMX生成的hal庫做組合設備時過于繁瑣 所以這里使用某大神的插件,可以集成在cubeMX里自動生成組合設備 有小bug會覆蓋生成文件里自己寫的內容,所以生成一次后注意保存 插件安裝 下載地址 https://github.com/alambe94/I-CUBE-USBD-Com…

【文獻閱讀】Capabilities of Gemini Models in Medicine

? Google DeepMind Google Research 發表于 2024-04-29 相關鏈接&#xff1a; 數據集&#xff1a;https://huggingface.co/datasets/katielink/med-gemini-medqa-relabeled 注&#xff1a;長EHR是長的電子健康記錄&#xff08;Electronic Health Record&#xff09; 未開…

網絡安全小知識課堂(最終完結版)

網絡安全入門 &#xff1a;從 “小白” 到 “守護者” 的蛻變之旅 寫在完結之際 歷經 13 篇的深度探索&#xff0c;我們從 DDoS 攻擊的 “流量洪水” 一路闖關到 HTTPS 的 “加密堡壘”&#xff0c;揭開了網絡安全世界的層層面紗。感謝每一位讀者的陪伴與互動&#xff0c;你們…

Php laravel 留言板 curd 實戰

1. 項目創建 首先我們用composer創建項目 &#xff0c; composer會根據當前的php版本 幫我們選擇支持的最高版本 composer create-project --prefer-dist laravel/laravel myblog laravel新版本比較激進 &#xff0c;需要最低 php7 支持 2. 項目配置 數據庫配置 &#xff0c…

HTTP 壓力測試工具autocannon(AI)

簡介 autocannon 是一款基于 Node.js 的高性能 HTTP 壓力測試工具&#xff0c;適用于評估 Web 服務的并發處理能力和性能瓶頸。 一、工具特點 高性能?&#xff1a;利用 Node.js 異步非阻塞機制模擬高并發請求?。?實時監控?&#xff1a;測試過程中動態展示請求統計和性能…

LVM 擴容詳解

目錄 一、LVM擴容 1. 查看磁盤分區情況&#xff1a; 2. 查看pv、vg、lv 情況 3. 將新硬盤分區初始化 4. 將初始化后的分區添加到VG中 5. 查看邏輯卷的設備路徑 6. VG分配給lv 二、擴展文件系統 1.確認文件系統類型 三、檢驗 一、LVM擴容 1. 查看磁盤分區情況&#xff1a; …

每日一題(小白)數組娛樂篇21

由于題意可知我們是要將對應的數字轉換為英文&#xff0c;我們要考慮兩點一個是進制的轉換&#xff0c;也就是類似于我們的十進制一到9就多一位&#xff0c;這里的進制就是Z進制也就是27進制一旦到26下一位則進位&#xff1b;另一方面要考慮數字的轉換也就是1~26對應A~Z。解決上…

python爬蟲:喜馬拉雅案例(破解sign值)

聲明&#xff1a; 本文章中所有內容僅供學習交流使用&#xff0c;不用于其他任何目的&#xff0c;嚴禁用于商業用途和非法用途&#xff0c;否則由此產生的一切后果均與作者無關&#xff01; 根據上一篇文章&#xff0c;我們破解了本網站的&#xff0c;手機號和密碼驗證&#x…

深入探討:Spring 如何接入 DeepSeek?

?在當今數字化浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;技術的迅猛發展深刻地改變著各個領域的技術格局。Java 作為一種廣泛應用于企業級開發的編程語言&#xff0c;其生態系統也在不斷演進以適應 AI 技術的融入。Spring 框架&#xff0c;作為 Java 生態中的中流…

VSCode運行,各類操作緩慢,如何清理

VSCode寫代碼&#xff0c;隨著項目逐步進展&#xff0c;代碼量在增加&#xff0c;依賴的第三方頭文件也在增加&#xff0c; 先是發現代碼提示的速度變慢&#xff0c; 后來格式化代碼速度太慢 然后c/c代碼的語法檢查有時候壓根就失敗&#xff0c;來個錯誤提示 還有source contro…

Elasticsearch:加快 HNSW 圖的合并速度

作者&#xff1a;來自 Elastic Thomas Veasey 及 Mayya Sharipova 過去&#xff0c;我們曾討論過搜索多個 HNSW 圖時所面臨的一些挑戰&#xff0c;以及我們是如何緩解這些問題的。當時&#xff0c;我們也提到了一些計劃中的改進措施。本文正是這項工作的成果匯總。 你可能會問…

人事|人事管理系統|基于Springboot+vue的人事管理系統設計與實現(源碼+數據庫+文檔)

人事管理系統 目錄 基于Springboot的人事管理系統設計與實現 一、前言 二、系統功能設計 三、系統實現 1、管理員登錄 2、員工管理 3、公告信息管理 4、公告類型管理 5、培訓管理 6、培訓類型管理 四、數據庫設計 1、實體ER圖 五、核心代碼 六、論文參考 七、最新…

2.4GHz射頻前端噪聲系數優化架構

2.4GHz射頻前端電路架構由信號處理鏈路、硬件模塊及性能規范構成&#xff0c;其系統組成與參數要求如下&#xff1a; 一、信號發射鏈路? 數字基帶信號通過DAC轉換為模擬信號? 調制電路將信號加載至本地振蕩器生成的2.4GHz載波? 功率放大器將信號強度提升至20-25dBm范圍? …

開源 LLM 應用開發平臺 Dify 全棧部署指南(Docker Compose 方案)

開源 LLM 應用開發平臺 Dify 全棧部署指南&#xff08;Docker Compose 方案&#xff09; 一、部署環境要求與前置檢查 1.1 硬件最低配置 組件要求CPU雙核及以上內存4GB 及以上磁盤空間20GB 可用空間 1.2 系統兼容性驗證 ? 官方支持系統&#xff1a; Ubuntu 20.04/22.04 L…

Trae AI 保姆級教程:從安裝到調試全流程指南

Trae AI 保姆級教程&#xff1a;從安裝到調試全流程指南 Trae AI 是字節跳動推出的一款 AI 原生集成開發環境(IDE)&#xff0c;專為中文開發者設計&#xff0c;集成了 Claude 3.5 和 GPT-4o 等先進 AI 模型&#xff0c;支持通過自然語言交互實現代碼生成、項目構建與調試。本教…

博物館小程序怎么做?從0到1打造數字化文化窗口

博物館小程序怎么做&#xff1f;從0到1打造數字化文化窗口 一、行業痛點&#xff1a;傳統博物館的數字化困局 在數字化浪潮下&#xff0c;傳統博物館普遍面臨三大挑戰&#xff1a; ??客流受限??&#xff1a;線下接待能力有限&#xff0c;難以觸達更廣泛人群 ??互動單一…