JAN's History
Spring AOP를 이용한 전처리와 후처리 구현방법 2탄!!(+무한참조 에러해결) 본문
이제 advice 메서드가 @Around를 통해 낚아채는 것을 확인했으니, 내부에 유효성검사 로직을 넣어주면
전처리 후처리 로직을 자동으로 실행할 수 있습니다.
@Around("execution(* com.cos.photogramstart.web.api.*Controller.*(..))")
public Object apiAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println(" web api 컨트롤러 ================");
Object[] args = proceedingJoinPoint.getArgs();
for (Object arg:args){
System.out.println("유효성검사하는 함수입니다.");
BindingResult bindingResult = (BindingResult) arg
}
}
앞전 1탄에서 proceedingJoinPoint를 통해 메서드가 가지고 있는 모든 정보에 접근할 수 있음을 알았는데요.
우선 메서드가 가지고 있는 매개변수에 접근해서 오브젝트 배열에 담아보겠습니다!
무한참조 에러 발생
그.러.나 이렇게 배열에 바로 넣게되면, 무한참조 에러가 발생할 수 있습니다.
저의 경우에도 User 데이터를 불러오면서 images 객체도 같이 담아오다보니 무한참조가 발생했거든요 ..ㅜㅜ
➡️sysout 에서 toString하다가 getter가 다 되다보니 무한참조가 발생했다고 보시면 됩니다!
그래서 저는 User 오브젝트에 images 객체를 제외한 toString()을 직접 만들어 해결했습니다.
에러 해결
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", name='" + name + '\'' +
", website='" + website + '\'' +
", bio='" + bio + '\'' +
", email='" + email + '\'' +
", phone='" + phone + '\'' +
", gender='" + gender + '\'' +
", profileImageUrl='" + profileImageUrl + '\'' +
", role='" + role + '\'' +
", createDate=" + createDate +
'}';
}
➡️보면 User 데이터를 가져올때 toString을 오버라이딩하여 image는 빼고 getter를 사용하도록 하여 에러를 해결했습니다.
이렇게 되면 정상적으로 세션정보를 다 가지고 오게 됩니다
이제 우리는 AOP를 사용해 @Around로 지정한 위치에서 전처리 후처리를 나누는 방법을 알았습니다.
그리고 proceedingJoinPoint로 지정한 위치에서 실행되는 메서드에 내부 data에 접근할 수 있는 방법까지 확인했습니다.
그러면 if를 걸어서 BindingResult값이 있으면 유효성검사를 실행할 수 있도록 하겠습니다!
📍 BindingResult : @Valid로 유효성 검사를 하는 로직에만 있는 변수입니다.
그리고, 각자 ApiController와 Controller에서 적어두었던 유효성 검사 로직을 가져와 붙여주면 끝입니다.
@Component //RestController, Service든 모든 것들이 Component를 상속해서 만들어져 있음.
@Aspect
public class ValidationAdvice {
@Around("execution(* com.cos.photogramstart.web.api.*Controller.*(..))")
public Object apiAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
// System.out.println(" web api 컨트롤러 ================");
Object[] args = proceedingJoinPoint.getArgs();
for (Object arg:args){
if(arg instanceof BindingResult){
//BindingResult : 유효성검사를 처리할 때 사용되는 객체
//arg가 BindingResult타입의 인자라면, 유효성 검사가 필요한 메서드라는 뜻!
System.out.println("유효성검사하는 함수입니다.");
BindingResult bindingResult = (BindingResult) arg;
if (bindingResult.hasErrors()) {
Map<String, String> errorMap = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
System.out.println("error.getDefaultMessage() = " + error.getDefaultMessage());
}
throw new CustomValidationApiException("유효성검사 실패함", errorMap);
}
}
}
//proceedingJoinPoint => profile 함수의 모든 곳에 접근할 수 있는 변수
//profile함수보다는 먼저 실행
return proceedingJoinPoint.proceed(); //이때 profile함수가 실행됨.
}
@Around("execution(* com.cos.photogramstart.web.*Controller.*(..))")
public Object advice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
// System.out.println(" web컨트롤러 ================");
Object[] args = proceedingJoinPoint.getArgs();
for (Object arg:args){
System.out.println("유효성검사하는 함수입니다.");
BindingResult bindingResult = (BindingResult) arg;
if (bindingResult.hasErrors()) {
Map<String, String> errorMap = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
System.out.println("error.getDefaultMessage() = " + error.getDefaultMessage());
}
throw new CustomValidationException("유효성검사 실패함",errorMap);
}
}
return proceedingJoinPoint.proceed(); //이때 profile함수가 실행됨.
}
}
그리고 원래 Controller에 있던 유효성검사 로직은 삭제해주면 됩니다
➡️유효성검사 로직을 AOP관점으로 분리하여 사용하니 댓글달기 로직도 깔끔해보입니다!
결과
➡️예시로 댓글내용 없이 댓글을 작성했을 경우에도 성공적으로 CustomValidationApiException이 발동하면서 유효성검사가 진행되는 것을 알 수 있습니다
이렇게 하면 하나하나 ApiController와 Controller에서 적어둬야했던 유효성검사 로직을 자동으로 발동시킬 수 있습니다!
'스프링' 카테고리의 다른 글
OAuth2 로그인 - 페이스북 개발자 센터로 페이스북 연동 로그인하기 2탄 (0) | 2024.06.03 |
---|---|
OAuth2 로그인 - 페이스북 개발자 센터로 페이스북 연동 로그인하기 (0) | 2024.06.01 |
Spring AOP를 이용한 전처리와 후처리 구현방법! (0) | 2024.05.25 |
Ajax통신을 사용하는 2가지 이유 ex) 회원가입, 좋아요, 댓글.. (0) | 2024.05.22 |
@ControllerAdvice, @ExceptionHandler로 에러처리하기 (0) | 2024.05.09 |