패키지 구조 상속 구조 ConcurCouponException 예외 클래스는 비즈니스 로직을 작성하다 발생하는 예외를 모아둘 최상위 클래스이다. ConcurCouponException을 상속받은 구조로 비즈니스 로직 관련 예외를 만든다.예를 들어 조회 대상이 없는 경우에 대한 예외를 정의하는 NotFoundException 등을 만든다. ErrorCodepublic enum ErrorCode { //400: BAD_REQUEST INVALID_REQUEST_ARGUMENT("잘못된 요청입니다."), COUPON_OVER_AMOUNT("발급 가능한 쿠폰 수량을 초과했습니다."), COUPON_OVER_AMOUNT_PER_MEMBER("한사람당 발급 가능한 쿠폰 수량을 초과했습니다.")..
분류 전체보기
목적멤버 쿠폰 발급에 대한 동시성 테스트테스트할 코드쿠폰 발급 API 요청 시 호출되는 issueMemberCoupon 메서드@Transactionalpublic void issueMemberCoupon(Long couponGroupId, Long memberId) { //쿠폰 그룹의 발급 가능여부 조회 CouponGroup couponGroup = findCouponGroupById(couponGroupId); Member member = findMemberById(memberId); LocalDateTime now = LocalDateTime.now(); //발행가능한지 여부 if (!couponGroup.getIsIssued()) { throw new B..
들어가기 전에 spring-security-jwt프로젝트를 진행하면서 Filter를 구현할 때, Filter가 아닌 OncePerRequestFilter를 상속하는 이유를 알아보자 클라이언트에 요청이 올때 가장 먼저 Filter를 호출하고 응답을 줄때는 가장 마지막으로 호출한다. Filter javax.servlet-api나 tomcat-embed-core를 사용하면 제공되는 Servlet Filter Interface이다. DispatcherServlet가 요청을 받기 전 앞단에 Filter에서 먼저 request를 받는다. package jakarta.servlet; import java.io.IOException; public interface Filter { public default void i..
AccesToken 만료시간이 지났을 때 Access token이 만료되었을 때는 재발급을 위해 Refresh Token이 이용된다. 이때 클라이언트에서 재발급을 위한 요청을 보내는데, 두 가지 구현 방법이 있다. 인가가 필요한 요청에 대해 access token이 만료되었을 경우 401 응답을 보내고, 응답을 받은 클라이언트는 refresh 요청을 보내 새로운 access token을 발급 받은 뒤 재요청을 보낸다. 클라이언트가 요청을 보내기 전, access token의 payload를 통해 만료 기한을 얻고 만료 기한이 지난 토큰이라면 refresh 요청을 보낸 후에 새로운 access token을 발급받아 원래 하려던 요청을 한다. 서버에서 매번 요청마다 토큰 유효성 검사를 하는데, 어차피 만료되..
고민 과정 상황 Access Token과 Refresh Token 발급하고 클라이언트에 어디에 담아 응답을 줄지 고민을 했다. 마찬가지로 클라이언트가 서버에 요청을 보낼때는 어디에 Access Token을 담아야 서버가 사용자 인증(JWT 검증)을 할 수 있을까? 의문 response body, 쿠키, 헤더에 담는 방법이 있느데 과연 어디에 담아 서버가 클라이언트에 응답(토큰 발급) / 클라이언트가 서버에 요청(사용자 인증)을 보내는게 맞는걸까? 결론 처음에 XSS보안을 고려해 클라이언트가 쿠키에 저장할 수 있도록 Access token과 Refresh token을 쿠키에 넣어 클라이언트에 보냈다. (set-cookie로 요청 헤더에 담음) -> 클라이언트가 토큰을 쿠키에 저장한다고 서버에서도 쿠키에 저..
목표 기능 회원가입 (깃허브 참고) 로그인 Access Token, Refresh Token 발급 Authorization Header 에 Access Token, Refresh Token 담아서 응답 보내기 서버에서 Access Token과 Refresh Token을 어디에 담아서 클라이언트에 응답을 줘야할지 고민했다. [JWT] JWT는 어디에 저장할까 [JWT] JWT는 어디에 저장할까 고민 과정 상황 처음에 XSS보안을 고려해 클라이언트가 쿠키에 저장할 수 있도록 Access token과 Refresh token을 쿠키에 넣어 클라이언트에 보냈다. (set-cookie로 요청 헤더에 담음) 의문 다른 블로그를 hohodu.tistory.com Redis 부분은 추후에 포스팅할 예정이다. 개발 환경..
들어가기 전에 Static pages - image, html, css, javascript 파일과 같이 컴퓨터에 저장되어 있는 파일들을 의미한다. - 웹 서버에서 요청에 알맞은 파일을 반환하며, 항상 동일한 페이지를 반환한다. (말 그대로 정적인 컨텐츠) - 웹 서버에서 제공한다. Dynamic pages - 들어온 요청에 맞게 동적으로 만들어진 컨텐츠를 의미한다. - 데이터베이스, 서버 내 로직 등을 활용해 만들어진 컨텐츠를 반환한다. - 웹 어플리케이션 서버에서 제공한다. Web Server HTTP 요청을 받아 Static contents를 제공하는 서버 (Ex. Apache Server, Nignx, ...) 기능 1: 정적인 컨텐츠 제공 WAS를 거치지 않고, 바로 요청한 컨텐츠를 제공할 수 ..
UUID란? 네트워크 상에서 고유성이 보장되는 id를 만들기 위한 표준 규약이다. UUID는 Universally Unique IDentifier의 약어이고 범용 고유 식별자라고 한다. 자바에서 UUID (UUID 4버전) -Java5 부터 UUID(Universally Unique IDentifier)를 생성하는 것이 가능 언제? 프로젝트를 수행하면서 S3이미지 서버에 저장할 파일 이름, 로그를 찍을때 쓰레드 아이디를 만들때 사용했다. 정리해보자면 고유성이 보장되는 id와 같은 것을 생성할 때 쓰인다. 1. 업로드된 파일명의 중복을 방지하기 위해 파일명을 변경할 때 사용. 2. 첨부파일 파일다운로드시 다른 파일을 예측하여 다운로드하는것을 방지하는데 사용. 3. 일련번호 대신 유추하기 힘든 식별자를 사용..
왜 사용하는가? 먼저 스프링 빈의 이벤트 사이클을 알아보자 스프링 빈의 이벤트 사이클 스프링 컨테이너 생성 -> 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 사용 -> 소멸 전 콜백 -> 스프링 종료 초기화 콜백: 빈이 생성되고 빈의 의존 관계 주입이 완료된 후 호출됩니다. 소멸전 콜백: 빈이 소멸되기 직전에 호출됩니다. -> 스프링 빈 생명주기 콜백 사용 방법 중에 하나가 @PostConstruct 와 @PreDestroy이다. @PostConstruct 객체의 초기화 부분 객체가 생성된 후 별도의 초기화 작업을 위해 실행하는 메소드에 적용 WAS가 띄워질때 bean이 생성된 다음 딱 한번만 실행 @PostConstruct public void init() { System.out.println(..
정적(Static) 이란? 정적(static)은 고정된이란 의미를 가지고 있습니다. Static이라는 키워드를 사용하여 Static변수(정적 필드)와 Static메소드(정적 메소드)를 만들 수 있습니다.( 이 둘을 합쳐 정적 멤버 또는 클래스 멤버라고 합니다.) 정적 필드와 정적 메소드는 객체(인스턴스)에 소속된 멤버가 아니라 클래스에 고정된 멤버입니다. 정적 멤버 생성 Static 키워드를 통해 생성된 정적멤버들은 메모리 구조상에서 Data영역에 저장되며 이는 메모리상에 한번 할당되면 프로그램이 종료될때 해제된다는 것을 의미한다. Class가 여러번 생성되어도 클래스 내부 Static변수는 딱 한번만 생성된다. 주로 클래스들이 할당 Garbage Collector가 관여하지 않음 모든 객체가 메모리를 ..