- mysql
- 스프링부트
- select
- 데이터베이스
- springboot
- AWS
- nginx
- sql
- 프로그래머스
- string
- 자바
- DI
- jpa
- java
- ORM
- join
- 1차원 배열
- hibernate
- spring boot
- Django
- spring security 6
- Docker
- PYTHON
- spring mvc
- SSL
- 스프링
- @transactional
- static
- 문자열
- spring
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
목록Java & Kotlin (88)
개발하는 자몽

스프링 시큐리티는 `@AuthenticationPrincipal` 애노테이션을 제공한다. 이는 `Authenticaiton.getPrincipal()`를 메서드 인자로 가져오는 데 사용되며, 보통은 `UserDetails` 타입이나 해당 타입의 커스텀 구현체로 가져오게 된다. `Authentication.getPrincipal()`에는 username, password(AuthenticationManager 구현에 따라 없을 수 있음), role과 같은 사용자 정보가 담겨있다. 간단하게 해당 애노테이션을 그대로 사용해도 되지만, 더 편리하게 사용할 수 있다. 이는 공식문서에서도 안내하고 있다. 실제로 구현해 보자. 여기서는 커스텀 애노테이션 이름을 `@CurrentUser`로 설정했다.import ..

📌 Spring Security 6.5.0 기준 작성 로그인을 구현할 때 보통 JWT를 많이 사용하는데, 이번에는 세션 기반으로 구현했다. 일단... JWT를 사용하여 로그인과 로그아웃을 구현하면 신경 쓸 것이 꽤 많다. 특히 로그아웃이 복잡한 것 같다. 사용자 인증을 위한 액세스 토큰(Access Token) 및 액세스 토큰 재발급을 위한 리프레시 토큰(Refresh Token) 생성요청 시 사용된 토큰이 유효한지 검증(만료, 변조 여부 등)로그아웃을 해도 액세스 토큰의 만료기간이 남아있다면 재사용 가능 → 이를 막기 위해 로그아웃 시 해당 액세스 토큰을 블랙리스트(저장소)에 저장 블랙리스트 저장소에 대한 액세스 속도를 높이기 위해 보통 Redis와 같은 인메모리 DB를 사용한다.한 번은 블랙..
if코틀린의 `if`문은 표현식(expression)으로, 아래와 같은 방식으로 변수에 값으로 할당될 수 있다. (삼항연산자를 풀어서 쓰는 느낌이다)fun main() { val a: Int = 100 val b: Int = 200 val c: Int c = if (a >= b) { a } else { b } println(c)} `null` 체크는 다음과 같이 할 수 있다. fun main() { val a: Int? = null if (a == null) { println("null check true") // print } else { println("a ..
요즘 스프링 개발 환경에서도 코틀린을 사용하는 경향이 꽤 보인다. 그래서 코틀린에 관심이 생겨서 찾아본 기본 문법! 변수 타입코틀린에는 `var`와 `val`라는 두 가지 형태의 변수가 존재한다.`var`: 초기화 이후에도 값 변경이 가능한 가변 변수`val`: 초기화 이후에는 값을 변경할 수 없는 불변 변수fun main() { var a = 1 a = 2 // 가변 변수이므로 값 변경 가능 val b = 1 b = 2 // 불변 변수이므로 에러 발생 var c: Int // 타입은 명시했으나, 초기화 하지 않은 상태 println(c) // 초기화 하지 않은 상태이므로 에러 발생 c = 1 // 초기화 println(c) // 1 출력}..

⚠️이 포스트는 지식 공유보다는 본인이 나중에 다시 보기 위해 작성하는 기록용입니다... build.gradledependencies { implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.boot:spring-boot-starter-security' ...} application.ymlspring: security.oauth2: client.registration: kakao: client-name: Kakao client-id: ${CLIENT_ID} client-secret: ${..
일반적으로 Spring 애플리케이션에서 application.yml에 정의된 값을 static 변수에서 사용할 수 없다. 따라서 Spring에서 제공하는 `@Value` 애노테이션으로 설정 파일에 정의된 값을 static 변수에 주입하면 에러가 발생한다. Java의 static 변수는 아래 시점에 메모리에 저장된다. 스프링 컨테이너(Application Context)가 로드되기 전 == 객체 생성 이전 == 의존성 주입을 받기 전 하지만 `@Value`는 의존 관계 주입 시점(인스턴스 수준)에서 동작한다. 이로 인해 의존성 주입을 받기 전에 메모리에 저장되는 static 변수에는 값을 주입할 수 없다. 이는 더 나아가서 클래스 레벨에도 동일하게 적용할 수 있다. `@Component` 애노테이션이..
상황1:N 관계가 얽혀있는 엔티티를 대상으로 Spring Data JPA를 이용해서 Pagination 조회를 하니 말로만 듣던 N+1 상황이 발생했다. 처음에는 일반적인 해결 방법인 Fetch Join을 사용하려고 했다. 더불어 중복을 방지하기 위해 `DISTINCT` 추가하려고 했다. 그러나 1:N 관계의 컬렉션을 Fetch Join 하면서 동시에 Pagination을 사용하는 것은 OutOfMemoryError가 발생할 수 있고, 이로 인해 `DISTINCT`를 적용할 수 없다고 한다. 그래서 찾은 다른 방법 중 가장 빠르고 쉬운 방법은 Batch Size를 설정하는 것이었다. 하이버네이트 Batch Size 하이버네이트에서 제공하는 `@BatchSize` 애노테이션이나 `batch_size`..
Gradle로 테스트를 빌드하다가 제목과 같은 에러를 만났다. 사실 처음에는 그냥 빌드하다가 위와 같은 정확한 에러명이 나오지 않아서 나중에 빌드할 때 아래 명령어를 사용했다. 그냥 빌드했을 때 실패했다고만 나오면 해당 옵션으로 시도하는 것을 추천한다👍./gradlew test -i # 윈도우 gitbash에서 실행 Note `-i / --info` 옵션은 로그 레벨을 INFO로 설정하는 것이다. 에러 내용을 봤을 때 yml/properties 파일에 작성한 프로퍼티 설정을 가져오면서 뭔가 문제가 있는 것 같았다. 그리고 역시나 `@Value`로 yml에 적힌 값을 가져올 때 오타가 있었다. 이 부분을 수정하고 다시 빌드하니 해당 에러는 더 이상 보이지 않았다! (관련 없는 다른 에러가 반겨주었..
지난 포스팅에 이어서 작성합니다.2024.10.02 - [Java] - Java/Spring 테스트 - 1 의존성의존성컴퓨터 공학에서 말하는 의존성(Dependency)은 결합(Coupling)과 같은 의미로, 다른 객체의 함수를 사용하는 상태를 말함 ⇒ A는 B를 사용하기만 해도 의존한다고 할 수 있음의존성을 약하게 만드는 기술 중 하나가 의존성 주입필요한 값을 `new`해서 직접 인스턴스화하는 것이 아닌 외부에서 넣어주는 것`new`를 이용하여 인스턴스화 하는 것은 하드 코딩의존성 주입은 의존성을 약화시키는 것, 의존성을 완전히 없애는 방식이 아님의존성 제거 == 객체 간의 협력 부정 / 시스템 간의 협력 부정대부분의 디자인 패턴이나 설계는 어떻게 하면 의존성을 약화시킬 수 있는지 고민한 결과..
에러 원인정말... 바보같은... 실수였다... 오류가 났던 테스트 코드는 아래와 같다. ... @PersistenceContext EntityManager em; @Test void test() { UserEntity userEntity = UserEntity.builder() .nickname("test") .email("test@example.com") .build(); userEntity = userRepository.save(userEntity); userService.sumTotalAmount(userEntity, 10_000L); ..