Spring AOP 를 활용해보자! - BindingResult 2편
Spring AOP 를 활용해보자! - BindingResult
https://github.com/pursue503/study-tdd GitHub - pursue503/study-tdd: TDD TDD . Contribute to pursue503/study-tdd development by creating an account on GitHub. github.com 최근 백엔드 지인과 TDD 로 회..
dev-jo.tistory.com
이전 글을 활용해서 BindingResult 를 처리해도 괜찮습니다
이번 편에서는 AOP 에서 모든것을 처리하는 방법 입니다.
https://github.com/pursue503/study-tdd/pull/22
AOP 에러 수정 by pursue503 · Pull Request #22 · pursue503/study-tdd
변경전 @Slf4j @RequiredArgsConstructor @RestController public class PostController { private final PostService postService; /** * 게시물 저장 요청을 받아 저장 처리후 반환값으로 저장된 게시물의 postId를 반환합니다. ...
github.com
최근에 레포에 BindingResult 를 활용한거에 대한 PR을 날렸는데
컨트롤러에서 BindingResult 변수를 사용하지 않으나 선언해두는 것이 조금 걸리네요.
해결방법이 없는지 찾아보도록 하겠습니다.
라는 코멘트를 받았다.
해당 내용에 나도 동의한다 굳이 사용하지 않는 BindingResult 를 컨트롤러에 남겨두는게 마음에 걸려
문서를 찾아보고 스프링 내부 구조를 뜯어봐서
클래스를 찾고 직접 AOP 에서 검증하도록 하였다.
변경전 코드
@Before("execution(* study.tdd.simpleboard.api..*Controller.*(..))")
public void bindingBefore(JoinPoint joinPoint) throws Throwable {
for (Object arg : joinPoint.getArgs()) {
if (arg instanceof BindingResult) {
BindingResult result = (BindingResult) arg;
if (result.hasErrors()) {
throw new InvalidPostParameterException(result, GeneralParameterErrorCode.INVALID_PARAMETER);
}
}
} // end for
} // end
변경후 코드
@Slf4j
@RequiredArgsConstructor
@Component
@Aspect
public class BindingResultAop {
private final Validator validator;
/**
*
* api 패키지 내부 컨트롤러 실행전에 실행
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Before("execution(* study.tdd.simpleboard.api..*Controller.*(..))")
public void bindingBefore(JoinPoint joinPoint) {
for (Object arg : joinPoint.getArgs()) {
BindingResult bindingResult = new BeanPropertyBindingResult(arg, arg.getClass().getName());
validator.validate(arg, bindingResult);
if (bindingResult.hasErrors()) {
throw new InvalidPostParameterException(bindingResult, GeneralParameterErrorCode.INVALID_PARAMETER);
}
} // end for
} // end
}
추가 및 변경사항
1. 모든 컨트롤러에서 BindingResult 파라미터 및 @Valid 제거 하였습니다.
2. AOP 에 Validator 주입 받도록 변경
3. AOP 에서 BindingResult 객체를 만들고 직접 검증하도록 변경
Validator 이란?
1. 검증을 하는 인터페이스 입니다.
2. org.springframework.validation.beanvalidation 에 있는 LoaclValidatorFactoryBean 이 클래스가 구현체
실제 구현체가 주입되는것을 확인하였습니다.
로직 설명
BindingResult bindResult = new BeanPropertyBindingResult(arg, arg.getClass().getName());
BeanPropertyBindingResult 로 바인딩 객체 생성
생성자로 객체와 객체의 이름을 주어야함
validator.validate(arg, bindingResult);
검증해서 어노테이션에 달린 조건을 위반할경우
그 내용이 bindingResult 에 담깁니다.
bindingResult.hasErrors() 메소드로 에러처리
요약
어노테이션을 사용하지 않고 직접 구현 클래스로 검증을 시도하였습니다.
컨트롤러에서 BindingResult 파라미터를 제거해도 올바르게 에러가 전달됩니다.
변경된 PR
https://github.com/pursue503/study-tdd/pull/23
Update Controller : BindingResult 제거 및 @Valid 제거 AOP 에서 검증하도록 변경 by pursue503 · Pull Request #23 ·
사용하지 않는 파라미터가 컨트롤러에 있는것은 이상하다는 의견을 받았습니다. 해당 의견에 동의합니다. 그래서 해결법을 찾아 보았습니다. 변경전 AOP @Before("execution(* study.tdd.simpleboard.api..*Cont
github.com