[TIL]2025.05.12

기 원·2025년 5월 12일

[Project] Spring-plus

목록 보기
8/8

2025-05-12 Spring Boot + Kotlin 기반 프로젝트


프로젝트 전환 및 기본 설정

1. Kotlin 기반 프로젝트

  • 기존 Java 기반 코드에서 Kotlin으로 전환.

2. 디렉토리 구조 정리

  • /src/main/kotlin에 코어 비즈니스 로직 이전.
  • /java/org.example.expert/kotlin/com.example.domain로 이전하며 패키지 통일.

3. 공통 설정 파일

  • application.yml 구성 완료.
  • .env 파일을 통해 외부 환경변수 분리.
  • SECRET_KEY, MYSQL_USERNAME 등 중요한 값들은 .env로 관리.

보안 / 인증 시스템 구축

1. JWT 유틸 클래스 구현 (JwtUtil.kt)

  • HS256 알고리즘 기반 JWT 생성 및 파싱 구현.
  • Claims 필드: userId, email, userRole, nickname
  • 만료 시간: 60분 설정.
@PostConstruct
fun init() {
    val bytes = Base64.getDecoder().decode(secretKey)
    key = Keys.hmacShaKeyFor(bytes)
}

2. JWT 필터 구현 (JwtAuthenticationFilter.kt)

  • OncePerRequestFilter 상속.
  • 토큰 유효 시 사용자 인증 정보를 SecurityContextHolder에 등록.

3. Spring Security 설정 (SecurityConfig.kt)

  • /auth/**는 허용
  • /admin/**은 ADMIN Role만 허용
  • 나머지는 모두 인증 필요
  • Stateless 정책, Form Login / HTTP Basic 비활성화
http.csrf().disable()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

사용자 기능

1. User 엔티티 변경

  • User.kt 클래스에 profileImage 필드 추가
  • fromAuthUser() 정적 팩토리 메서드 도입
  • changePassword, updateRole, setProfileImage 메서드 구현

2. UserController.kt / UserService.kt

  • 비밀번호 변경 API (/users, PUT)
  • 사용자 정보 조회 (/users/{userId})
  • 닉네임 기반 조회 캐싱 적용 (@Cacheable)

3. 예외 처리

  • InvalidRequestException, AuthException, ServerException 공통 처리
  • @RestControllerAdvice 기반 글로벌 예외 핸들러 작성

Todo 기능

1. Todo 엔티티 및 Repository

  • title, contents, weather, user 필드 포함
  • findAllByOrderByModifiedAtDesc() / searchTodos() 구현

2. TodoService.kt

  • saveTodo: 날씨 조회 후 저장
  • getTodos: 페이징 조회
  • searchTodos: 조건부 검색
  • getTodo: 단일 조회 + User join
  • searchTodosWithFilters: QueryDSL 기반 키워드, 닉네임, 날짜 필터링

3. TodoQueryRepositoryImpl

  • Projections.constructor를 사용한 커스텀 DTO 매핑
  • groupBy, leftJoin, where절 조합
  • count 쿼리 분리하여 페이징 대응

Manager 기능

1. Manager 엔티티

  • @ManyToOne 연관관계로 User, Todo를 소유
  • @Id, @GeneratedValue 전략

2. ManagerService

  • saveManager: 일정 작성자와의 매칭 여부 검증
  • deleteManager: 생성자만 삭제 가능
  • getManagers: 일정별 매니저 목록 조회

3. 로깅 기능 추가

  • Log 엔티티: action, details, createdAt
  • LogService: @Transactional(REQUIRES_NEW)로 로그 분리 저장
  • 예외가 발생해도 로그는 저장되도록 finally 블록 활용

Comment 기능

1. Comment 엔티티

  • contents, user, todo, Timestamped 상속

2. CommentService

  • saveComment: Todo 존재 여부 확인 후 저장
  • getComments: TodoId로 Comment 전체 조회 (User Join 포함)

AWS / Redis 설정

1. S3 연동 (S3Service.kt)

  • updateFile() 메서드 구현
  • 파일은 UUID 기반 이름으로 업로드

2. Redis 설정 (RedisConfig.kt)

  • RedisTemplateRedisCacheManager 설정
  • TTL: 10분

테스트 및 부가사항

  • @GetMapping("/health"): Health Check API 제공
  • AdminAccessLoggingAspect: AOP로 UserController.getUser() 접근 로그 출력
  • 전체적으로 !!, ?, lateinit 등의 코틀린 nullable 처리 점검
  • @Valid, @RequestParam, @PageableDefault 등 다양한 Spring 어노테이션 적용

해결한 문제 목록

PasswordEncoder Bean 오류

  • 의존성 누락 문제였으나, Spring Boot Starter Security로 해결됨

JwtUtil 빈 주입 실패

  • SECRET_KEY 환경변수가 .env로만 존재할 때 인식 안됨
  • 해결 방법: .env -> OS 환경변수로 등록 or .yml에 직접 선언

LocalDateTime?LocalDateTime 타입 불일치

  • Repository 쿼리에서 nullable 타입이어서 타입 mismatch 오류 발생
  • todoRepository.searchTodos(pageable, weather, start ?: now(), end ?: now()) 식으로 대응

@Generated Q 클래스 import 오류

  • Kotlin, Java 혼합 프로젝트에서 QueryDSL의 Q클래스 import 경로 꼬임 문제 발생
  • 해결: QueryDSL 생성 경로를 kotlin에 통일 / querydslDir 명시

profile
노력하고 있다니까요?

0개의 댓글