diff --git a/build.gradle b/build.gradle index 977ee02..8957bc1 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,8 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' // Swagger - implementation 'io.springfox:springfox-boot-starter:3.0.0' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-api:2.1.0' // Redis implementation 'org.springframework.boot:spring-boot-starter-data-redis' diff --git a/src/main/generated/com/web/stard/domain/notification/dto/SseMapStructImpl.java b/src/main/generated/com/web/stard/domain/notification/dto/SseMapStructImpl.java new file mode 100644 index 0000000..7d2469f --- /dev/null +++ b/src/main/generated/com/web/stard/domain/notification/dto/SseMapStructImpl.java @@ -0,0 +1,25 @@ +package com.web.stard.domain.notification.dto; + +import com.web.stard.domain.notification.domain.Notification; +import javax.annotation.processing.Generated; + +@Generated( + value = "org.mapstruct.ap.MappingProcessor", + date = "2024-10-04T15:46:49+0900", + comments = "version: 1.5.3.Final, compiler: javac, environment: Java 17.0.9 (Oracle Corporation)" +) +public class SseMapStructImpl implements SseMapStruct { + + @Override + public ResponseNotificationDto toResponseNotification(Notification notification) { + if ( notification == null ) { + return null; + } + + ResponseNotificationDto.ResponseNotificationDtoBuilder responseNotificationDto = ResponseNotificationDto.builder(); + + responseNotificationDto.notification( notification ); + + return responseNotificationDto.build(); + } +} diff --git a/src/main/java/com/web/stard/domain/member/api/SignController.java b/src/main/java/com/web/stard/domain/member/api/SignController.java index 72d35ac..7e55d8a 100644 --- a/src/main/java/com/web/stard/domain/member/api/SignController.java +++ b/src/main/java/com/web/stard/domain/member/api/SignController.java @@ -3,7 +3,7 @@ import com.web.stard.domain.member.dto.MemberRequestDto; import com.web.stard.domain.member.application.SignService; import com.web.stard.global.dto.TokenInfo; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; @@ -22,19 +22,19 @@ public class SignController { private final SignService signService; - @ApiOperation(value = "로그인") + @Operation(description = "로그인") @PostMapping("/sign-in") public ResponseEntity signIn(@Valid @RequestBody MemberRequestDto.SignInDto dto) { return ResponseEntity.ok().body(signService.signIn(dto)); } - @ApiOperation(value = "토큰 재발급") + @Operation(description = "토큰 재발급") @PostMapping("/reissue") public ResponseEntity reissue(HttpServletRequest request) { return ResponseEntity.ok().body(signService.reissue(request)); } - @ApiOperation(value = "로그아웃") + @Operation(description = "로그아웃") @PostMapping("/sign-out") public void signOut(HttpServletRequest request) { signService.signOut(request); diff --git a/src/main/java/com/web/stard/domain/notification/controller/NotificationController.java b/src/main/java/com/web/stard/domain/notification/controller/NotificationController.java index b16897d..92719a1 100644 --- a/src/main/java/com/web/stard/domain/notification/controller/NotificationController.java +++ b/src/main/java/com/web/stard/domain/notification/controller/NotificationController.java @@ -2,8 +2,7 @@ import com.web.stard.domain.notification.service.NotificationService; import com.web.stard.global.config.jwt.JwtTokenProvider; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Description; import org.springframework.http.MediaType; @@ -22,8 +21,8 @@ public class NotificationController { // EventSource API는 기본적으로 HTTP 헤더를 수정할 수 없어 Authorization 헤더 추가x -> 쿼리 파라미터나 쿠키를 사용하여 토큰을 전송 @GetMapping(value = "/subscribe", produces = MediaType.TEXT_EVENT_STREAM_VALUE) - @ApiOperation(value = "클라이언트에서 구독하기 위한 subscribe 메서드 / 로그인 시 사용") - @ApiImplicitParam(name = "lastEventId", value = "SSE 연결이 끊겼을 때, 클라이언트가 수신한 마지막 데이터의 id") + @Operation(description = "클라이언트에서 구독하기 위한 subscribe 메서드 / 로그인 시 사용") +// @ApiImplicitParam(name = "lastEventId", value = "SSE 연결이 끊겼을 때, 클라이언트가 수신한 마지막 데이터의 id") public SseEmitter subscribe(@RequestHeader(value = "Last-Event-ID", required = false, defaultValue = "") String lastEventId, @RequestParam(value = "token", required = false) String token) { Authentication authentication = jwtTokenProvider.getAuthentication(token); @@ -50,8 +49,8 @@ public void sendData(@RequestParam(value = "token", required = false) String tok } @GetMapping(value = "/subscribe/{userId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) - @ApiOperation(value = "클라이언트에서 구독하기 위한 subscribe 메서드 / 로그인 시 사용") - @ApiImplicitParam(name = "lastEventId", value = "SSE 연결이 끊겼을 때, 클라이언트가 수신한 마지막 데이터의 id") + @Operation(description = "클라이언트에서 구독하기 위한 subscribe 메서드 / 로그인 시 사용") +// @ApiImplicitParam(name = "lastEventId", value = "SSE 연결이 끊겼을 때, 클라이언트가 수신한 마지막 데이터의 id") public SseEmitter subscribeByUserId(@PathVariable String userId, @RequestHeader(value = "Last-Event-ID", required = false, defaultValue = "") String lastEventId) { return notificationService.subscribe(userId, lastEventId); diff --git a/src/main/java/com/web/stard/global/config/swagger/SwaggerConfig.java b/src/main/java/com/web/stard/global/config/swagger/SwaggerConfig.java index 07aa791..7dd0c16 100644 --- a/src/main/java/com/web/stard/global/config/swagger/SwaggerConfig.java +++ b/src/main/java/com/web/stard/global/config/swagger/SwaggerConfig.java @@ -1,60 +1,35 @@ package com.web.stard.global.config.swagger; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.servers.Server; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.ApiKey; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.SecurityReference; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; - -import java.util.List; @Configuration public class SwaggerConfig { @Bean - public Docket restAPI() { - return new Docket(DocumentationType.OAS_30) - .apiInfo(apiInfo()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.web.stard")) - .paths(PathSelectors.any()) - .build() - .securitySchemes(List.of(apiKey())) - .securityContexts(List.of(securityContext())); - } - - private ApiInfo apiInfo() { - return new ApiInfoBuilder() - .title("Web Spring Boot REST API") - .version("1.0.0") - .description("Web swagger api") - .build(); - } - - // JWT SecurityContext 구성 - private SecurityContext securityContext() { - return SecurityContext.builder() - .securityReferences(defaultAuth()) - .build(); + public OpenAPI umcAPI() { + Info info = new Info().title("STARD API").description("STARD API 명세").version("0.0.1"); + + String jwtSchemeName = "JWT TOKEN"; + SecurityRequirement securityRequirement = new SecurityRequirement().addList(jwtSchemeName); + + Components components = new Components() + .addSecuritySchemes(jwtSchemeName, new SecurityScheme() + .name(jwtSchemeName) + .type(SecurityScheme.Type.HTTP) + .scheme("Bearer") + .bearerFormat("JWT")); + + return new OpenAPI() + .addServersItem(new Server().url("/")) + .info(info) + .addSecurityItem(securityRequirement) + .components(components); } - - private List defaultAuth() { - AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); - AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; - authorizationScopes[0] = authorizationScope; - return List.of(new SecurityReference("Authorization", authorizationScopes)); - } - - // ApiKey 정의 - private ApiKey apiKey() { - return new ApiKey("Authorization", "Authorization", "header"); - } - } \ No newline at end of file