# spring boot 3 使用swagger
###### tags: `spring`
原打算直接使用swagger2、swagger ui但貌似spring boot 3改版後,該lib就無人維護,故改用SpringDoc
step1. add dependency
```xml=
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.0.0</version>
</dependency>
```
step2. add config file,若有security需求需要再增加SecurityItem、components
```java=
@OpenAPIDefinition
@Configuration
public class SpringdocConfig {
    @Bean
    public OpenAPI baseOpenAPI(){
        final String securitySchemeName = "bearerAuth";
        return new OpenAPI()
        .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
        .components(
                new Components()
                        .addSecuritySchemes(securitySchemeName,
                                new SecurityScheme()
                                        .name(securitySchemeName)
                                        .type(SecurityScheme.Type.HTTP)
                                        .scheme("bearer")
                                        .bearerFormat("JWT")
                        )
        )
        .info(new Info().title("Spring Doc").version("1.0.0").description("Spring doc"));
    }
}
```
step2.5. 若有security需求需要,需於security的設定裡設定
```java=
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    return http
            .csrf(csrf -> csrf.disable())
            .oauth2ResourceServer(OAuth2ResourceServerConfigurer :: jwt)
            .addFilterBefore(new AuthorizationCheckFilter(), BasicAuthenticationFilter.class)
            .authorizeHttpRequests(auth -> auth
                    .requestMatchers(
                            "/v3/api-docs/**",
                            "/swagger-ui/**",
                            "/user/login").permitAll()
                    .anyRequest().authenticated()
            )
            .build();
}
```
自設定登入Filter也需要增加
```java=
public class AuthorizationCheckFilter extends OncePerRequestFilter {
    private static final String[] AUTH_WHITELIST = {
            // -- Swagger UI v3
            "/v3/api-docs/**",
            "v3/api-docs/**",
            "/swagger-ui/**",
            "swagger-ui/**",
            "/user/login"
    };
    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException {
        String path = req.getServletPath();
        AntPathMatcher pathMatcher = new AntPathMatcher();
        boolean contains = Arrays.stream(AUTH_WHITELIST).anyMatch(x -> pathMatcher.match(x,path));
        //如果不是登入or Swagger-ui就攔截
        if(!contains){
            // 登入驗證
        }else{
            chain.doFilter(req, res);
        }
    }
}
```
step3. add controller description
```java=
@Tag(name = "controller 區塊名稱")
@RestController
public class testController {
    @Operation(summary = "標題",description = "敘述")
    @ApiResponses({
            @ApiResponse(responseCode="401",description="沒有權限"),
            @ApiResponse(responseCode="404",description="找不到路徑")
    })
    @GetMapping("/")
    public String test() {
        return "hello";
    }
}
```
有Security需求的人
進入後,Swagger頁面上半部右邊就會多一個Authorize按鈕供輸入token,輸入後api就不會被擋了
ref
[Day 21 - Spring Boot Swagger API 文件神器](https://ithelp.ithome.com.tw/articles/10247180)
[springdoc-openapi v1.6.14](https://springdoc.org/#getting-started)
[How To Add OpenAPI And Swagger To Spring Boot Application](https://youtu.be/A_RWUcTqHBI)
[Swagger with Spring Security](https://waynestalk.com/spring-security-jwt-jpa-springdoc-explained/)