공통기능을 필터링처리 하면 코드를 재활용해서 훨씬 코드를 깔끔하게 쓸 수 있다.
이 공통기능을 AOP처리할거다.
AOP기능 구현에 앞서 dependency 를 추가해줘야한다.
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop
implementation 'org.springframework.boot:spring-boot-starter-aop:2.4.5'
ValidationAdvice
- 유효성 검사를 공통으로 처리하는 곳
- @Aspect가 있어야 AOP를 처리할 수 있는 핸들러가 된다.
- api쪽 advice와 그냥 advice를 만든다.
1.
@Before(): 특정 함수 실행직전에 실행
@After(): 특정 함수 실행 직후에 실행
@Around(): 특정 함수 실행직전부터 직후에 관여
2.
- ....web.api의 모든 컨트롤러의 모든 메소드의 모든 매개변수 가 실행될때 작동된다.
- proceedingJoinPoint : api의 Controller중에 특정 함수가 실행됐으면 proceedingJoinPoint가
그 함수의 매개변수 뿐만 아니라 내부의 모든 정보에 접근할 수 있다.
- 예를들어 profile함수가 실행되는 순간 그 함수의 모든 정보를 proceedingJoinPoint가 담고 profile함수 실행 이전에 apiAdvice가 먼저 실행된다.
- 그 이후 return proceedingJoinPoint.proceed(); 가 실행되며 profile함수가 실행된다.
3.
proceedingJoinPoint.getArgs() 를 통해 함수의 매개변수에 접근해서 리스트에 담는다.
만약에 매개변수 중에서 BindingResult라는 타입이 있으면
-> 해당 arg를 BindingResult형으로 다운 캐스팅
-> 만약 bindingResult에 에러가 있다면 -> 유효성 검사 실행
@Component
@Aspect
public class ValidationAdvice {
@Around("execution(* com.jghan.instaclone.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 bindingResult = (BindingResult) arg;
if (bindingResult.hasErrors()) {
Map<String, String> errorMap = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
}
throw new CustomValidationApiException("유효성 검사 실패함", errorMap);
}
}
}
return proceedingJoinPoint.proceed(); //prfofile함수가 실행됨
}
@Around("execution(* com.jghan.instaclone.web.*Controller.*(..))")
public Object advice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object[] args = proceedingJoinPoint.getArgs();
for(Object arg: args){
if(arg instanceof BindingResult){
BindingResult bindingResult = (BindingResult) arg;
if (bindingResult.hasErrors()) {
Map<String, String> errorMap = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
}
throw new CustomValidationException("유효성 검사 실패함", errorMap);
}
}
}
return proceedingJoinPoint.proceed();
}
}
'Study > SpringBoot' 카테고리의 다른 글
[스프링부트 개념정리] 어노테이션, 리플렉션 (0) | 2022.06.16 |
---|---|
[스프링부트 개념정리] Ioc, DI란 (0) | 2022.06.16 |
[Springboot] 댓글기능 구현 (0) | 2022.06.01 |
[Springboot] 프로필 사진 변경 (0) | 2022.05.31 |
[Springboot] 좋아요 기능 추가 - 2 뷰에 렌더링 (0) | 2022.05.29 |