From 09ec53f13a0c82c87e37e4cad8a23a17cf9603c9 Mon Sep 17 00:00:00 2001 From: hyungjun <115551339+sukangpunch@users.noreply.github.com> Date: Sun, 22 Mar 2026 15:36:30 +0900 Subject: [PATCH 01/11] =?UTF-8?q?refactor:=20Java,=20SpringBoot=20?= =?UTF-8?q?=EB=B2=84=EC=A0=84=20=EC=97=85=20&=20JJWT=20=EB=B2=84=EC=A0=84?= =?UTF-8?q?=20=EC=97=85=20(#702)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: Spring Boot, Java 및 주요 의존성 버전업, commons-lang3 추가 - SpringBoot 버전업 (-> 3.5.11) - Java 버전업 (-> 21) - JJWT 버전업 (-> 0.12.6) - 기존 EnumUtils deprecate 대응을 위해 org.apache.commons:commons-lang3 의존성 추가 * refactor: JJWT deprecated API를 신규 API로 마이그레이션 * chore: ci/cd 파일 및 도커파일Java 17 → 21, Spring Boot 버전 업 반영 * test: @MockBean, @SpyBean을 @MockitoBean, @MockitoSpyBean으로 마이그레이션 Co-Authored-By: Claude Sonnet 4.6 * fix: 누락된 변경사항 추가 * refactor: 코드래빗 리뷰사항 적용 - 테스트에서 Token 생성 시, TTL을 30초로 수정 - TTL이 너무 짧으면 테스트가 간헐적으로 꺠질 위험 존재 --- .github/workflows/ci.yml | 4 +- .github/workflows/dev-cd.yml | 4 +- .github/workflows/prod-cd.yml | 4 +- Dockerfile | 2 +- build.gradle | 14 +++--- claude.md | 4 +- .../auth/client/AppleOAuthClient.java | 7 +-- .../AppleOAuthClientSecretProvider.java | 18 ++++---- .../auth/token/JwtTokenProvider.java | 30 ++++++++----- .../AdminHostUniversityServiceTest.java | 4 +- .../RefreshTokenCookieManagerTest.java | 4 +- .../auth/service/JwtTokenProviderTest.java | 45 +++++++++++-------- .../auth/service/oauth/OAuthServiceTest.java | 4 +- .../signup/SignUpTokenProviderTest.java | 17 ++++--- .../chat/service/ChatServiceTest.java | 4 +- .../post/service/PostCommandServiceTest.java | 4 +- .../service/MentorApplicationServiceTest.java | 4 +- .../news/service/NewsCommandServiceTest.java | 4 +- .../score/service/ScoreServiceTest.java | 4 +- .../TokenAuthenticationProviderTest.java | 29 ++++++------ .../filter/SignOutCheckFilterTest.java | 11 ++--- .../filter/TokenAuthenticationFilterTest.java | 15 ++++--- .../siteuser/service/MyPageServiceTest.java | 4 +- .../UnivApplyInfoQueryServiceTest.java | 4 +- 24 files changed, 133 insertions(+), 111 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 794b49827..fdbacdd87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,10 +15,10 @@ jobs: - name: Checkout the code uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: '17' + java-version: '21' distribution: 'temurin' - name: Setup Gradle diff --git a/.github/workflows/dev-cd.yml b/.github/workflows/dev-cd.yml index 294d6b57a..82eec9d37 100644 --- a/.github/workflows/dev-cd.yml +++ b/.github/workflows/dev-cd.yml @@ -21,10 +21,10 @@ jobs: uses: actions/checkout@v4 # --- Java, Gradle 설정 --- - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: '17' + java-version: '21' distribution: 'temurin' - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 diff --git a/.github/workflows/prod-cd.yml b/.github/workflows/prod-cd.yml index 0d6bc082d..aed7b4077 100644 --- a/.github/workflows/prod-cd.yml +++ b/.github/workflows/prod-cd.yml @@ -27,10 +27,10 @@ jobs: uses: actions/checkout@v4 # --- Java, Gradle 설정 --- - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: '17' + java-version: '21' distribution: 'temurin' - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 diff --git a/Dockerfile b/Dockerfile index f598c9395..741b95685 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # JDK 버전 설정 -FROM eclipse-temurin:17-jdk +FROM eclipse-temurin:21-jdk # JAR_FILE 변수 정의 ARG JAR_FILE=./build/libs/solid-connection-0.0.1-SNAPSHOT.jar diff --git a/build.gradle b/build.gradle index 4694747d9..6a21cd9bb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,15 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.1.5' - id 'io.spring.dependency-management' version '1.1.4' - id 'org.flywaydb.flyway' version '9.16.3' + id 'org.springframework.boot' version '3.5.11' + id 'io.spring.dependency-management' version '1.1.7' + id 'org.flywaydb.flyway' version '10.15.0' } group = 'com.example' version = '0.0.1-SNAPSHOT' java { - sourceCompatibility = '17' + sourceCompatibility = '21' } configurations { @@ -43,8 +43,9 @@ dependencies { // Security implementation 'org.springframework.security:spring-security-config' implementation 'org.springframework.security:spring-security-web' - implementation 'io.jsonwebtoken:jjwt:0.9.1' - runtimeOnly 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359' // for jjwt + implementation 'io.jsonwebtoken:jjwt-api:0.12.6' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6' // Monitoring implementation 'org.springframework.boot:spring-boot-starter-actuator' @@ -70,6 +71,7 @@ dependencies { implementation 'io.awspring.cloud:spring-cloud-aws-starter-parameter-store:3.0.4' implementation 'org.hibernate.validator:hibernate-validator' implementation 'org.springframework.boot:spring-boot-starter-websocket' + implementation 'org.apache.commons:commons-lang3' // Database Proxy implementation 'net.ttddyy.observation:datasource-micrometer:1.2.0' diff --git a/claude.md b/claude.md index af2e96a4d..95edb60f7 100644 --- a/claude.md +++ b/claude.md @@ -7,8 +7,8 @@ Solid Connect Server는 교환학생 준비생을 위해 대학 정보, 멘토 매칭, 모의지원 기능 등을 제공하는 교환학생 지원 통합 플랫폼입니다. -- **언어**: Java 17 -- **프레임워크**: Spring Boot 3.1.5 +- **언어**: Java 21 +- **프레임워크**: Spring Boot 3.5.11 - **빌드 도구**: Gradle - **데이터베이스**: MySQL (주), Redis (캐싱) - **마이그레이션**: Flyway diff --git a/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClient.java b/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClient.java index 9b17214ee..ff9828cd7 100644 --- a/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClient.java +++ b/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClient.java @@ -81,9 +81,10 @@ private MultiValueMap buildFormData(String code) { private String parseEmailFromToken(PublicKey applePublicKey, String idToken) { try { return Jwts.parser() - .setSigningKey(applePublicKey) - .parseClaimsJws(idToken) - .getBody() + .verifyWith(applePublicKey) + .build() + .parseSignedClaims(idToken) + .getPayload() .get("email", String.class); } catch (Exception e) { throw new CustomException(INVALID_APPLE_ID_TOKEN); diff --git a/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClientSecretProvider.java b/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClientSecretProvider.java index a5a5cd315..04ec939cf 100644 --- a/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClientSecretProvider.java +++ b/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClientSecretProvider.java @@ -5,16 +5,15 @@ import com.example.solidconnection.auth.client.config.AppleOAuthClientProperties; import com.example.solidconnection.common.exception.CustomException; import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; import jakarta.annotation.PostConstruct; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Base64; import java.util.Date; import lombok.RequiredArgsConstructor; -import org.apache.tomcat.util.codec.binary.Base64; import org.springframework.stereotype.Component; /* @@ -42,20 +41,19 @@ public String generateClientSecret() { Date expiration = new Date(now.getTime() + TOKEN_DURATION); return Jwts.builder() - .setHeaderParam("alg", "ES256") - .setHeaderParam(KEY_ID_HEADER, appleOAuthClientProperties.keyId()) - .setSubject(appleOAuthClientProperties.clientId()) - .setIssuer(appleOAuthClientProperties.teamId()) - .setAudience(appleOAuthClientProperties.clientSecretAudienceUrl()) - .setExpiration(expiration) - .signWith(SignatureAlgorithm.ES256, privateKey) + .header().add(KEY_ID_HEADER, appleOAuthClientProperties.keyId()).and() + .subject(appleOAuthClientProperties.clientId()) + .issuer(appleOAuthClientProperties.teamId()) + .audience().add(appleOAuthClientProperties.clientSecretAudienceUrl()).and() + .expiration(expiration) + .signWith(privateKey, Jwts.SIG.ES256) .compact(); } private PrivateKey loadPrivateKey() { try { String secretKey = appleOAuthClientProperties.secretKey(); - byte[] encoded = Base64.decodeBase64(secretKey); + byte[] encoded = Base64.getMimeDecoder().decode(secretKey); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); KeyFactory keyFactory = KeyFactory.getInstance("EC"); return keyFactory.generatePrivate(keySpec); diff --git a/src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java b/src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java index 262cfdcd3..082d6e793 100644 --- a/src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java +++ b/src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java @@ -7,11 +7,14 @@ import com.example.solidconnection.auth.token.config.JwtProperties; import com.example.solidconnection.common.exception.CustomException; import io.jsonwebtoken.Claims; +import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.Date; import java.util.Map; +import javax.crypto.SecretKey; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -32,16 +35,18 @@ public String generateToken(Subject subject, Map customClaims, D } private String generateJwtTokenValue(String subject, Map claims, Duration expireTime) { - Claims jwtClaims = Jwts.claims().setSubject(subject); - jwtClaims.putAll(claims); Date now = new Date(); Date expiredDate = new Date(now.getTime() + expireTime.toMillis()); - return Jwts.builder() - .setClaims(jwtClaims) - .setIssuedAt(now) - .setExpiration(expiredDate) - .signWith(SignatureAlgorithm.HS512, jwtProperties.secret()) - .compact(); + JwtBuilder builder = Jwts.builder() + .subject(subject) + .issuedAt(now) + .expiration(expiredDate); + claims.forEach(builder::claim); + return builder.signWith(getSigningKey()).compact(); + } + + private SecretKey getSigningKey() { + return Keys.hmacShaKeyFor(jwtProperties.secret().getBytes(StandardCharsets.UTF_8)); } @Override @@ -61,9 +66,10 @@ public T parseClaims(String token, String claimName, Class claimType) { private Claims parseJwtClaims(String token) { try { return Jwts.parser() - .setSigningKey(jwtProperties.secret()) - .parseClaimsJws(token) - .getBody(); + .verifyWith(getSigningKey()) + .build() + .parseSignedClaims(token) + .getPayload(); } catch (Exception e) { throw new CustomException(INVALID_TOKEN); } diff --git a/src/test/java/com/example/solidconnection/admin/service/AdminHostUniversityServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/AdminHostUniversityServiceTest.java index 14200ebb8..b28d5bf01 100644 --- a/src/test/java/com/example/solidconnection/admin/service/AdminHostUniversityServiceTest.java +++ b/src/test/java/com/example/solidconnection/admin/service/AdminHostUniversityServiceTest.java @@ -29,7 +29,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -55,7 +55,7 @@ class AdminHostUniversityServiceTest { @Autowired private UnivApplyInfoFixtureBuilder univApplyInfoFixtureBuilder; - @SpyBean + @MockitoSpyBean private CustomCacheManager cacheManager; @Nested diff --git a/src/test/java/com/example/solidconnection/auth/controller/RefreshTokenCookieManagerTest.java b/src/test/java/com/example/solidconnection/auth/controller/RefreshTokenCookieManagerTest.java index 57b6ad97e..2496b65d8 100644 --- a/src/test/java/com/example/solidconnection/auth/controller/RefreshTokenCookieManagerTest.java +++ b/src/test/java/com/example/solidconnection/auth/controller/RefreshTokenCookieManagerTest.java @@ -18,7 +18,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.boot.web.server.Cookie.SameSite; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -35,7 +35,7 @@ class RefreshTokenCookieManagerTest { @Autowired private TokenProperties tokenProperties; - @MockBean + @MockitoBean private RefreshTokenCookieProperties refreshTokenCookieProperties; private final String domain = "example.com"; diff --git a/src/test/java/com/example/solidconnection/auth/service/JwtTokenProviderTest.java b/src/test/java/com/example/solidconnection/auth/service/JwtTokenProviderTest.java index 506019478..d7a1a6f8e 100644 --- a/src/test/java/com/example/solidconnection/auth/service/JwtTokenProviderTest.java +++ b/src/test/java/com/example/solidconnection/auth/service/JwtTokenProviderTest.java @@ -11,12 +11,15 @@ import com.example.solidconnection.common.exception.ErrorCode; import com.example.solidconnection.support.TestContainerSpringBootTest; import io.jsonwebtoken.Claims; +import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.Date; import java.util.HashMap; import java.util.Map; +import javax.crypto.SecretKey; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -77,9 +80,10 @@ class 토큰을_생성한다 { private Duration getActualExpireTime(String token) { Claims claims = Jwts.parser() - .setSigningKey(jwtProperties.secret()) - .parseClaimsJws(token) - .getBody(); + .verifyWith(getSigningKey()) + .build() + .parseSignedClaims(token) + .getPayload(); return Duration.ofMillis(claims.getExpiration().getTime() - claims.getIssuedAt().getTime()); } } @@ -114,8 +118,7 @@ class 토큰으로부터_subject_를_추출한다 { @Test void subject_가_없는_토큰의_subject_를_추출하면_예외가_발생한다() { // given - Claims claims = Jwts.claims(new HashMap<>()); - String subjectNotExistingToken = createExpiredToken(claims); + String subjectNotExistingToken = createExpiredToken(new HashMap<>()); String subjectBlankToken = tokenProvider.generateToken(new Subject(" "), expectedExpireTime); // when, then @@ -155,8 +158,9 @@ class 토큰으로부터_claim_을_추출한다 { @Test void 유효하지_않은_토큰의_claim_을_추출하면_예외가_발생한다() { // given - Claims expectedClaims = Jwts.claims(new HashMap<>(Map.of(claimKey, claimValue))); - String token = createExpiredToken(expectedClaims); + Map claims = new HashMap<>(); + claims.put(claimKey, claimValue); + String token = createExpiredToken(claims); // when assertThatCode(() -> tokenProvider.parseClaims(token, claimKey, String.class)) @@ -184,19 +188,22 @@ class 토큰으로부터_claim_을_추출한다 { private String createExpiredToken(String subject) { return Jwts.builder() - .setSubject(subject) - .setIssuedAt(new Date()) - .setExpiration(new Date(System.currentTimeMillis() - 1000)) - .signWith(SignatureAlgorithm.HS256, jwtProperties.secret()) + .subject(subject) + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() - 1000)) + .signWith(getSigningKey()) .compact(); } - private String createExpiredToken(Claims claims) { - return Jwts.builder() - .setClaims(claims) - .setIssuedAt(new Date()) - .setExpiration(new Date(System.currentTimeMillis() - 1000)) - .signWith(SignatureAlgorithm.HS256, jwtProperties.secret()) - .compact(); + private String createExpiredToken(Map claims) { + JwtBuilder builder = Jwts.builder() + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() - 1000)); + claims.forEach(builder::claim); + return builder.signWith(getSigningKey()).compact(); + } + + private SecretKey getSigningKey() { + return Keys.hmacShaKeyFor(jwtProperties.secret().getBytes(StandardCharsets.UTF_8)); } } diff --git a/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthServiceTest.java index 2dd430fba..209bd95d7 100644 --- a/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthServiceTest.java +++ b/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthServiceTest.java @@ -18,7 +18,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; @DisplayName("OAuth 서비스 테스트") @TestContainerSpringBootTest @@ -30,7 +30,7 @@ class OAuthServiceTest { @Autowired private SiteUserFixture siteUserFixture; - @MockBean + @MockitoBean private OAuthClientMap oauthClientMap; private final AuthType authType = AuthType.KAKAO; diff --git a/src/test/java/com/example/solidconnection/auth/service/signup/SignUpTokenProviderTest.java b/src/test/java/com/example/solidconnection/auth/service/signup/SignUpTokenProviderTest.java index aff6a50d4..b54a181d2 100644 --- a/src/test/java/com/example/solidconnection/auth/service/signup/SignUpTokenProviderTest.java +++ b/src/test/java/com/example/solidconnection/auth/service/signup/SignUpTokenProviderTest.java @@ -17,9 +17,11 @@ import com.example.solidconnection.siteuser.domain.AuthType; import com.example.solidconnection.support.TestContainerSpringBootTest; import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.Date; +import javax.crypto.SecretKey; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -27,7 +29,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; @TestContainerSpringBootTest @DisplayName("회원가입 토큰 제공자 테스트") @@ -39,7 +41,7 @@ class SignUpTokenProviderTest { @Autowired private TokenProvider tokenProvider; - @SpyBean + @MockitoSpyBean private TokenStorage tokenStorage; @Autowired @@ -163,11 +165,12 @@ class 주어진_회원가입_토큰을_검증한다 { } private String createExpiredToken() { + SecretKey signingKey = Keys.hmacShaKeyFor(jwtProperties.secret().getBytes(StandardCharsets.UTF_8)); return Jwts.builder() - .setSubject(email) - .setIssuedAt(new Date()) - .setExpiration(new Date(System.currentTimeMillis() - 1000)) - .signWith(SignatureAlgorithm.HS256, jwtProperties.secret()) + .subject(email) + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() - 1000)) + .signWith(signingKey) .compact(); } } diff --git a/src/test/java/com/example/solidconnection/chat/service/ChatServiceTest.java b/src/test/java/com/example/solidconnection/chat/service/ChatServiceTest.java index 7cfb3dec0..68bb31e55 100644 --- a/src/test/java/com/example/solidconnection/chat/service/ChatServiceTest.java +++ b/src/test/java/com/example/solidconnection/chat/service/ChatServiceTest.java @@ -38,7 +38,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.BDDMockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -72,7 +72,7 @@ class ChatServiceTest { @Autowired private ChatAttachmentFixture chatAttachmentFixture; - @MockBean + @MockitoBean private SimpMessagingTemplate simpMessagingTemplate; private SiteUser user; diff --git a/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java b/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java index c752c11e4..a8ef1d25f 100644 --- a/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java +++ b/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java @@ -39,7 +39,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.multipart.MultipartFile; @@ -50,7 +50,7 @@ class PostCommandServiceTest { @Autowired private PostCommandService postCommandService; - @MockBean + @MockitoBean private S3Service s3Service; @Autowired diff --git a/src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java b/src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java index 8987cbe5d..49e69e976 100644 --- a/src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java +++ b/src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java @@ -27,7 +27,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.mock.web.MockMultipartFile; @TestContainerSpringBootTest @@ -49,7 +49,7 @@ public class MentorApplicationServiceTest { @Autowired private MentorApplicationFixture mentorApplicationFixture; - @MockBean + @MockitoBean private S3Service s3Service; private SiteUser user; diff --git a/src/test/java/com/example/solidconnection/news/service/NewsCommandServiceTest.java b/src/test/java/com/example/solidconnection/news/service/NewsCommandServiceTest.java index 7911da88e..95cde320d 100644 --- a/src/test/java/com/example/solidconnection/news/service/NewsCommandServiceTest.java +++ b/src/test/java/com/example/solidconnection/news/service/NewsCommandServiceTest.java @@ -29,7 +29,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.multipart.MultipartFile; @@ -43,7 +43,7 @@ class NewsCommandServiceTest { @Autowired private NewsProperties newsProperties; - @MockBean + @MockitoBean private S3Service s3Service; @Autowired diff --git a/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java b/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java index 2522dc962..0f2e27366 100644 --- a/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java +++ b/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java @@ -26,7 +26,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.mock.web.MockMultipartFile; @TestContainerSpringBootTest @@ -42,7 +42,7 @@ class ScoreServiceTest { @Autowired private LanguageTestScoreRepository languageTestScoreRepository; - @MockBean + @MockitoBean private S3Service s3Service; @Autowired diff --git a/src/test/java/com/example/solidconnection/security/authentication/TokenAuthenticationProviderTest.java b/src/test/java/com/example/solidconnection/security/authentication/TokenAuthenticationProviderTest.java index c8715f81a..9c2c77f84 100644 --- a/src/test/java/com/example/solidconnection/security/authentication/TokenAuthenticationProviderTest.java +++ b/src/test/java/com/example/solidconnection/security/authentication/TokenAuthenticationProviderTest.java @@ -13,8 +13,9 @@ import com.example.solidconnection.siteuser.fixture.SiteUserFixture; import com.example.solidconnection.support.TestContainerSpringBootTest; import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; import java.net.PasswordAuthentication; +import java.nio.charset.StandardCharsets; import java.util.Date; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -43,6 +44,8 @@ void setUp() { user = siteUserFixture.사용자(); } + private static final long VALID_TOKEN_TTL_MS = 30 * 1000L; + @Test void 처리할_수_있는_타입인지를_반환한다() { // given @@ -115,28 +118,28 @@ class 예외가_발생한다 { private String createValidToken(long id) { return Jwts.builder() - .setSubject(String.valueOf(id)) - .setIssuedAt(new Date()) - .setExpiration(new Date(System.currentTimeMillis() + 1000)) - .signWith(SignatureAlgorithm.HS256, jwtProperties.secret()) + .subject(String.valueOf(id)) + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() + VALID_TOKEN_TTL_MS)) + .signWith(Keys.hmacShaKeyFor(jwtProperties.secret().getBytes(StandardCharsets.UTF_8))) .compact(); } private String createExpiredToken() { return Jwts.builder() - .setSubject(String.valueOf(user.getId())) - .setIssuedAt(new Date()) - .setExpiration(new Date(System.currentTimeMillis() - 1000)) - .signWith(SignatureAlgorithm.HS256, jwtProperties.secret()) + .subject(String.valueOf(user.getId())) + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() - VALID_TOKEN_TTL_MS)) + .signWith(Keys.hmacShaKeyFor(jwtProperties.secret().getBytes(StandardCharsets.UTF_8))) .compact(); } private String createWrongSubjectTypeToken() { return Jwts.builder() - .setSubject("subject") - .setIssuedAt(new Date()) - .setExpiration(new Date(System.currentTimeMillis() + 1000)) - .signWith(SignatureAlgorithm.HS256, jwtProperties.secret()) + .subject("subject") + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() + VALID_TOKEN_TTL_MS)) + .signWith(Keys.hmacShaKeyFor(jwtProperties.secret().getBytes(StandardCharsets.UTF_8))) .compact(); } } diff --git a/src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java b/src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java index 2667671cd..372d7ed67 100644 --- a/src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java +++ b/src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java @@ -10,10 +10,11 @@ import com.example.solidconnection.common.exception.CustomException; import com.example.solidconnection.support.TestContainerSpringBootTest; import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; import jakarta.servlet.FilterChain; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.Objects; import org.junit.jupiter.api.BeforeEach; @@ -98,10 +99,10 @@ void setUp() { private String createToken(String subject) { return Jwts.builder() - .setSubject(subject) - .setIssuedAt(new Date()) - .setExpiration(new Date(System.currentTimeMillis() + 1000)) - .signWith(SignatureAlgorithm.HS256, jwtProperties.secret()) + .subject(subject) + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() + 1000)) + .signWith(Keys.hmacShaKeyFor(jwtProperties.secret().getBytes(StandardCharsets.UTF_8))) .compact(); } diff --git a/src/test/java/com/example/solidconnection/security/filter/TokenAuthenticationFilterTest.java b/src/test/java/com/example/solidconnection/security/filter/TokenAuthenticationFilterTest.java index d0b7d8963..e54a50e22 100644 --- a/src/test/java/com/example/solidconnection/security/filter/TokenAuthenticationFilterTest.java +++ b/src/test/java/com/example/solidconnection/security/filter/TokenAuthenticationFilterTest.java @@ -14,16 +14,17 @@ import com.example.solidconnection.siteuser.fixture.SiteUserFixture; import com.example.solidconnection.support.TestContainerSpringBootTest; import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; import jakarta.servlet.FilterChain; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import java.nio.charset.StandardCharsets; import java.util.Date; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.core.context.SecurityContextHolder; @@ -41,7 +42,7 @@ class TokenAuthenticationFilterTest { @Autowired private SiteUserFixture siteUserFixture; - @MockBean // 이 테스트코드에서 사용자를 조회할 필요는 없으므로 MockBean 으로 대체 + @MockitoBean // 이 테스트코드에서 사용자를 조회할 필요는 없으므로 MockBean 으로 대체 private SiteUserDetailsService siteUserDetailsService; private HttpServletRequest request; @@ -93,10 +94,10 @@ void setUp() { private String createTokenWithExpiration(Date expiration) { return Jwts.builder() - .setSubject("1") - .setIssuedAt(new Date()) - .setExpiration(expiration) - .signWith(SignatureAlgorithm.HS256, jwtProperties.secret()) + .subject("1") + .issuedAt(new Date()) + .expiration(expiration) + .signWith(Keys.hmacShaKeyFor(jwtProperties.secret().getBytes(StandardCharsets.UTF_8))) .compact(); } diff --git a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java index 89180fe41..7a8463a65 100644 --- a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java +++ b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java @@ -54,7 +54,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.mock.web.MockMultipartFile; import org.springframework.security.crypto.password.PasswordEncoder; @@ -65,7 +65,7 @@ class MyPageServiceTest { @Autowired private MyPageService myPageService; - @MockBean + @MockitoBean private S3Service s3Service; @Autowired diff --git a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java index b04d2d609..c0222c8f2 100644 --- a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java +++ b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java @@ -23,7 +23,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; @TestContainerSpringBootTest @DisplayName("대학 지원 정보 조회 서비스 테스트") @@ -32,7 +32,7 @@ class UnivApplyInfoQueryServiceTest { @Autowired private UnivApplyInfoQueryService univApplyInfoQueryService; - @SpyBean + @MockitoSpyBean private UnivApplyInfoRepository univApplyInfoRepository; @Autowired From d0f9ccb1c2b20a0252c5d45f0b4b3635e20dafed Mon Sep 17 00:00:00 2001 From: whqtker Date: Wed, 1 Apr 2026 22:45:18 +0900 Subject: [PATCH 02/11] =?UTF-8?q?refactor:=20ANT=5FPATH=5FMATCHER=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/filter/HttpLoggingFilter.java | 16 ++++++++++------ src/main/resources/application.yml | 4 ---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/example/solidconnection/common/filter/HttpLoggingFilter.java b/src/main/java/com/example/solidconnection/common/filter/HttpLoggingFilter.java index 74f2dfa6c..ae0535a7d 100644 --- a/src/main/java/com/example/solidconnection/common/filter/HttpLoggingFilter.java +++ b/src/main/java/com/example/solidconnection/common/filter/HttpLoggingFilter.java @@ -13,16 +13,20 @@ import org.slf4j.MDC; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; -import org.springframework.util.AntPathMatcher; +import org.springframework.http.server.PathContainer; import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.web.util.pattern.PathPattern; +import org.springframework.web.util.pattern.PathPatternParser; @Slf4j @RequiredArgsConstructor @Component public class HttpLoggingFilter extends OncePerRequestFilter { - private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher(); - private static final List EXCLUDE_PATTERNS = List.of("/actuator/**"); + private static final PathPatternParser PATH_PATTERN_PARSER = new PathPatternParser(); + private static final List EXCLUDE_PATTERNS = List.of( + PATH_PATTERN_PARSER.parse("/actuator/**") + ); private static final List EXCLUDE_QUERIES = List.of("token"); private static final String MASK_VALUE = "****"; @@ -60,9 +64,9 @@ protected void doFilterInternal( } private boolean isExcluded(HttpServletRequest req) { - String path = req.getRequestURI(); - for (String p : EXCLUDE_PATTERNS) { - if (PATH_MATCHER.match(p, path)) { + PathContainer path = PathContainer.parsePath(req.getRequestURI()); + for (PathPattern p : EXCLUDE_PATTERNS) { + if (p.matches(path)) { return true; } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 7b3bffa28..ef5b5a74d 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -18,10 +18,6 @@ spring: max-file-size: 10MB max-request-size: 10MB - mvc: - path match: - matching-strategy: ANT_PATH_MATCHER - management: endpoints: web: From d711528c5a0f076837c9d2ddba5039faabf86317 Mon Sep 17 00:00:00 2001 From: whqtker Date: Wed, 1 Apr 2026 22:49:00 +0900 Subject: [PATCH 03/11] =?UTF-8?q?refactor:=20min-spare=20=EC=9E=98?= =?UTF-8?q?=EB=AA=BB=EB=90=9C=20prefix=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ef5b5a74d..5e5590f44 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -9,15 +9,16 @@ spring: - optional:classpath:/config/application-variable.yml - aws-parameterstore:/solid-connection/common/ - tomcat: - threads: - min-spare: 20 # default 10 - servlet: multipart: max-file-size: 10MB max-request-size: 10MB +server: + tomcat: + threads: + min-spare: 20 # default 10 + management: endpoints: web: From 9579e5427aa0b30ec7fb6817d4eb204df9c8fa99 Mon Sep 17 00:00:00 2001 From: whqtker Date: Wed, 1 Apr 2026 23:45:52 +0900 Subject: [PATCH 04/11] =?UTF-8?q?refactor:=20spring.jpa.database=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/config/application-db.yml | 3 --- src/test/resources/application.yml | 1 - 2 files changed, 4 deletions(-) diff --git a/src/main/resources/config/application-db.yml b/src/main/resources/config/application-db.yml index cd461ea38..589c58fd9 100644 --- a/src/main/resources/config/application-db.yml +++ b/src/main/resources/config/application-db.yml @@ -9,7 +9,6 @@ spring: ddl-auto: none generate-ddl: false show-sql: false - database: mysql defer-datasource-initialization: false datasource: @@ -31,7 +30,6 @@ spring: ddl-auto: validate generate-ddl: false show-sql: false - database: mysql defer-datasource-initialization: false datasource: @@ -53,7 +51,6 @@ spring: ddl-auto: create generate-ddl: true show-sql: true - database: mysql defer-datasource-initialization: true properties: hibernate: diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 5eed9f7fa..b2459f4ca 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -10,7 +10,6 @@ spring: ddl-auto: create generate-ddl: true show-sql: true - database: mysql properties: hibernate: format_sql: true From 50be7517c3c4f8b141d0ed26101d6778aa80859f Mon Sep 17 00:00:00 2001 From: whqtker Date: Wed, 1 Apr 2026 23:59:51 +0900 Subject: [PATCH 05/11] =?UTF-8?q?refactor:=20spring.datasource.driverClass?= =?UTF-8?q?Name=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/config/application-db.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/main/resources/config/application-db.yml b/src/main/resources/config/application-db.yml index 589c58fd9..10e59165f 100644 --- a/src/main/resources/config/application-db.yml +++ b/src/main/resources/config/application-db.yml @@ -11,9 +11,6 @@ spring: show-sql: false defer-datasource-initialization: false - datasource: - driverClassName: com.mysql.cj.jdbc.Driver - flyway: enabled: true locations: classpath:db/migration @@ -32,9 +29,6 @@ spring: show-sql: false defer-datasource-initialization: false - datasource: - driverClassName: com.mysql.cj.jdbc.Driver - flyway: enabled: true locations: classpath:db/migration @@ -60,8 +54,5 @@ spring: init: mode: always - datasource: - driverClassName: com.mysql.cj.jdbc.Driver - flyway: enabled: false From 43e5633ca7426d6095b15e5ccf96f9e3b00a0d0e Mon Sep 17 00:00:00 2001 From: whqtker Date: Thu, 2 Apr 2026 00:14:47 +0900 Subject: [PATCH 06/11] =?UTF-8?q?refactor:=20JJWT=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EC=97=85=EC=97=90=20=EB=94=B0=EB=A5=B8=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=9E=84=ED=8F=AC=ED=8A=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/LanguageTestScoreFilterRepositoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/example/solidconnection/score/repository/custom/LanguageTestScoreFilterRepositoryImpl.java b/src/main/java/com/example/solidconnection/score/repository/custom/LanguageTestScoreFilterRepositoryImpl.java index d8f42f6a5..bcd999a09 100644 --- a/src/main/java/com/example/solidconnection/score/repository/custom/LanguageTestScoreFilterRepositoryImpl.java +++ b/src/main/java/com/example/solidconnection/score/repository/custom/LanguageTestScoreFilterRepositoryImpl.java @@ -2,7 +2,7 @@ import static com.example.solidconnection.score.domain.QLanguageTestScore.languageTestScore; import static com.example.solidconnection.siteuser.domain.QSiteUser.siteUser; -import static io.jsonwebtoken.lang.Strings.hasText; +import static org.springframework.util.StringUtils.hasText; import com.example.solidconnection.admin.dto.LanguageTestResponse; import com.example.solidconnection.admin.dto.LanguageTestScoreSearchResponse; From 37d4e445531312989fc87ed94a1c9172c8917a6a Mon Sep 17 00:00:00 2001 From: whqtker Date: Thu, 2 Apr 2026 00:33:51 +0900 Subject: [PATCH 07/11] =?UTF-8?q?refactor:=20cloud.aws.stack.auto=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/config/application-cloud.yml | 5 ----- src/test/resources/application.yml | 2 -- 2 files changed, 7 deletions(-) diff --git a/src/main/resources/config/application-cloud.yml b/src/main/resources/config/application-cloud.yml index 634b0cb6a..b55fc98b9 100644 --- a/src/main/resources/config/application-cloud.yml +++ b/src/main/resources/config/application-cloud.yml @@ -2,8 +2,3 @@ spring: config: activate: on-profile: local, dev, prod, loadtest - -cloud: - aws: - stack: - auto: false diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index b2459f4ca..28bd16f8a 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -24,8 +24,6 @@ cloud: secret-key: access-key region: static: ap-northeast-2 - stack: - auto: false s3: bucket: solid-connection-uploaded url: From cb3df94644366a8a758f7da1300024147d538f67 Mon Sep 17 00:00:00 2001 From: whqtker Date: Thu, 2 Apr 2026 09:30:39 +0900 Subject: [PATCH 08/11] =?UTF-8?q?refactor:=20parameter=20store=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EB=B2=84=EC=A0=84=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6a21cd9bb..02e066023 100644 --- a/build.gradle +++ b/build.gradle @@ -68,7 +68,7 @@ dependencies { // Etc implementation platform('software.amazon.awssdk:bom:2.41.4') implementation 'software.amazon.awssdk:s3' - implementation 'io.awspring.cloud:spring-cloud-aws-starter-parameter-store:3.0.4' + implementation 'io.awspring.cloud:spring-cloud-aws-starter-parameter-store:3.4.2' implementation 'org.hibernate.validator:hibernate-validator' implementation 'org.springframework.boot:spring-boot-starter-websocket' implementation 'org.apache.commons:commons-lang3' From 9f2521ccd7fdea05d6a35d2edbb473a71717973a Mon Sep 17 00:00:00 2001 From: whqtker Date: Thu, 2 Apr 2026 09:53:13 +0900 Subject: [PATCH 09/11] =?UTF-8?q?refactor:=20redis=20deprecated=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9E=90=20=EA=B5=90=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solidconnection/common/config/redis/RedisConfig.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/solidconnection/common/config/redis/RedisConfig.java b/src/main/java/com/example/solidconnection/common/config/redis/RedisConfig.java index f94443580..f3041b02d 100644 --- a/src/main/java/com/example/solidconnection/common/config/redis/RedisConfig.java +++ b/src/main/java/com/example/solidconnection/common/config/redis/RedisConfig.java @@ -3,6 +3,7 @@ import static com.example.solidconnection.redis.RedisConstants.CREATE_CHANNEL; import com.example.solidconnection.cache.CacheUpdateListener; +import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -49,7 +50,7 @@ public RedisTemplate redisTemplate() { public RedisTemplate objectRedisTemplate() { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setKeySerializer(new StringRedisSerializer()); - redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class)); + redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(new ObjectMapper(), Object.class)); redisTemplate.setConnectionFactory(redisConnectionFactory()); return redisTemplate; } From 6b2f85d17460e68a6a0ca98f803e4e41f1810a49 Mon Sep 17 00:00:00 2001 From: whqtker Date: Thu, 2 Apr 2026 10:07:01 +0900 Subject: [PATCH 10/11] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=EC=97=90=EC=84=9C=20=ED=8C=8C=EB=9D=BC?= =?UTF-8?q?=EB=AF=B8=ED=84=B0=20=EC=8A=A4=ED=86=A0=EC=96=B4=20=EA=B5=AC?= =?UTF-8?q?=EC=84=B1=20=EB=B9=84=ED=99=9C=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/application.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 28bd16f8a..34f19fa77 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -1,4 +1,8 @@ spring: + cloud: + aws: + parameterstore: + enabled: false # db data: From e31f41b43ea6d09f7d8775906c7245d67b5af700 Mon Sep 17 00:00:00 2001 From: whqtker Date: Thu, 2 Apr 2026 11:37:59 +0900 Subject: [PATCH 11/11] =?UTF-8?q?docs:=20=EC=8A=A4=ED=94=84=EB=A7=81?= =?UTF-8?q?=EB=B6=80=ED=8A=B8=20=EB=B2=84=EC=A0=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- claude.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/claude.md b/claude.md index 95edb60f7..fb2d436a1 100644 --- a/claude.md +++ b/claude.md @@ -167,7 +167,7 @@ public class UserCreateResponse { ... } ### Core Framework -- **Spring Boot 3.1.5**: 스프링 부트 +- **Spring Boot 3.5.11**: 스프링 부트 - **Spring Security**: JWT 기반 인증 - **Spring Data JPA**: ORM - **QueryDSL**: 동적 쿼리 생성