AuthRequestDto에 회원가입 시 필요한 정보들을 입력할 수 있도록 클래스를 구성했다.
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class AuthRequestDto {
@Size(min=4)
@Pattern(regexp = "[a-z0-9]")
private String username;
@Size(min=8)
private String password;
}
username과 password를 각각 입력받는다.
username은 최소 4자 이상, password는 최소 8자 이상이어야 한다.
그리고 username은 영어 소문자와 숫자로 구성되어야 한다.
그래서 각각 Lombok의 @Size과 @Pattern 에너테이션을 달아주었다.
그런데 .. 오류가 났다 !!! ..
Resolved [org.springframework.web.bind.MethodArgumentNotValidException:
Validation failed for argument [0] in public
...
default message [username],[Ljakarta.validation.constraints.Pattern$Flag;@1ac8a603,[a-z0-9]];
default message ["[a-z0-9]"와 일치해야 합니다]] ]
[a-z0-9]
와 일치해야지 .. 조건을 그렇게 준건데 ..?
는 무슨 .. 패턴을 잘못 주었다.
시작과 종료를 의미하는 ^
과 $
를 양 옆에 붙여주었어야 했는데 !!
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class AuthRequestDto {
@Size(min=4)
@Pattern(regexp = "^[a-z0-9]$")
private String username;
@Size(min=8)
private String password;
}
이렇게 수정해서 테스트를 해보았더니, 오류 .. 가 또 발생했다
오류 메시지가 일치했다! 패턴 준게 뭔가가 잘못됐나 ..
패턴 주는 방법이 잘못되었다 !
기존에 하던 방식이랑 약간 다르게 패턴을 주었더니, 잘못 준 듯 하다 ..
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class AuthRequestDto {
@Size(min=4)
@Pattern(regexp = "^[a-z0-9]+$")
private String username;
@Size(min=8)
private String password;
}
내가 빠뜨린 점은 저 $
기호 앞에 +
기호를 붙여야 한다는 점이다 !
저 +
기호는, 앞의 패턴이 최소 한 번 이상이라는 조건을 의미한다.
나는 @Pattern 위에 @Size 조건을 따로 주었는데, 한 번에 주는 방법도 있다
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class AuthRequestDto {
@Pattern(regexp = "^[a-z0-9]{4,}$")
private String username;
@Size(min=8)
private String password;
}
이렇게 @Pattern
에너테이션 안에, 글자 수에 대한 조건도 함께 부여할 수 있다
Validation 조건을 주는 것에 아직 익숙하지 않은 것 같다.
이전에는 @Pattern(regexp = "^[a-zA-Z0-9]{8,15}$")
등 이런 형태로 사용을 해서,
+
기호를 사용해야 한다는 점을 몰랐었다.
@Size
에너테이션을 따로 달아줄거라면, 패턴의 조건에 대한 +
기호를 써주어야 한다 !
쿠키에 토큰을 담아주는 과정에서, cookie.setPath("/") 라는 코드가 있는데
어떤 의미인지 모르고 그냥 사용하다가 궁금해져서 찾아보았다.
(Cookie는 jakarta.servlet.http.Cookie 이다.)
Cookie cookie = new Cookie("Authorization", token); // Name-Value
cookie.setPath("/");
쿠키를 생성하고, Authorization
이라는 이름으로 token(위에서 만듦)
을 담아준다.
그리고 cookie
의 setPath("/");
코드를 작성하여 사용한다.
setPath()
메서드는 메서드 이름에서 유추할 수 있듯이 쿠키의 경로를 설정하는 데 사용한다.
경로는 HTTP 요청을 할 때, 해당 쿠키를 보낼 서버의 URL의 하위 집합
을 지정하는 방법이라고 한다.
쿠키의 기본 동작이 쿠키를 설정한 URL 경로에 대해서만 전송하기 때문이다.
내가 작성했던 코드처럼 경로를 "/" 로 설정하게 되면, 도메인 전체에 걸쳐서 동작하는 도메인 전용 쿠키를 만들게 된다고 한다.
즉, 해당 도메인에 속한 모든 요청에 대해 쿠키가 전송되는 것이다.
URL에 특정한 경로가 있던지 없던지 도메인에 속한 모든 요청에 대해서 쿠키가 전송된다고 한다.
예를 들어서, 도메인이 "light.com" 에서 경로를 "/"로 쿠키를 설정한다고 가정해보자.
"light.com/home" , "light.com/info" 등 "light.com"으로 시작하는 모든 요청에 쿠키가 전송된다.
하지마 "high.light.com"과 같은 서브 도메인에 속한 요청이나, 다른 도메인으로의 요청에는 쿠키가 전송되지 않는다.
단, 도메인 전용 쿠키 설정 시는 주의해야 할 점이 있다.
동일한 도메인에서 실행되는 다른 애플리케이션들에도 영향을 미칠 수 있기 때문에, 보안에 유의해야 한다.
일반적으로는 쿠키를 실제로 필요로 하는 URL에 대해서만 더 구체적인 경로를 설정하는 것이 좋다고 한다.
@PostConstruct : https://zorba91.tistory.com/223
게시글, 댓글에 대한 엔티티를 생성할 때, Timestamp 파일을 따로 만들어서 상속받아 사용했다.
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class Timestamp {
@CreatedDate
@Column(updatable = false) // 이후에는 값이 수정되지 않음
@Temporal(TemporalType.TIMESTAMP)
private LocalDateTime createdAt;
@LastModifiedDate
@Column
@Temporal(TemporalType.TIMESTAMP)
private LocalDateTime modifiedAt;
}
여기서 사용하는 에너테이션에 대해서 정리해보려고 한다 !
@MappedSuperclass
: 객체에서 공통 매핑 정보가 필요할 때, 부모 클래스에 선언하고 속성만 상속받아서 사용하고 싶을 경우 부모 클래스에 달아주는 에너테이션이다.
@Temporal(TemporalType.TIMESTAMP)
: 날짜 타입을 매핑할 때 사용하는 에너테이션으로, TemporalType은 세 가지가 있다
public enum TemporalType {
/** Map as <code>java.sql.Date</code> */
DATE,
/** Map as <code>java.sql.Time</code> */
TIME,
/** Map as <code>java.sql.Timestamp</code> */
TIMESTAMP
}
Auditing
: 누가, 언제 접근했는지 모든 요청과 응답에 대해서 관리한다.
나의 경우는, 언제 접근했는지에 대한 정보만 필요해서 생성일자와 수정일자에 대한 필드만 생성했다.
@EntityListeners(AuditingEntityListener.class)
: @EntityListeners
에너테이션은, 엔티티를 DB에 반영하기 전에 커스텀 콜백을 요청할 수 있다. 나는 Auditing 기능을 사용할 것이기 때문에, JPA에서 제공해주는 AuditingEntityListener.class
를 넣어주면 된다.
@EnableAuditing
: Auditing 기능을 사용하기 위해서 Application.java 파일에 붙여주는 에너테이션이다.
연관관계가 있는 엔티티를 조회하는 경우, 지연 로딩(FetchType.LAZY)
으로 설정되어 있으면 쿼리 실행 시
select 되지 않고 proxy 객체를 만들어서 엔티티가 적용시킨다.
이후에 그 proxy 객체를 호출할 때마다 select 쿼리가 실행된다.
이런 연관 관계가 지연로딩으로 설정되어 있는 경우, fetch 조인을 사용해 여러 번의 쿼리를 한 번에 해결할 수 있다.
@EntityGraph
는 Data JPA에서 fetch 조인을 어노테이션으로 사용할 수 있게 한 기능이다.
@EntityGraph(attributePaths = {'조인할 엔티티 필드명'})
이렇게 사용할 수 있다 ! (메소드 위에 붙여주는 형식으로 사용하는 듯 하다)