Aspect 를 이용한 공통 BindingResult 처리 방법
validation 을 다음과 같이 처리를 한다.
VO에서 Vaildation 관련 설정
@Data
@JsonInclude(Include.NON_NULL)
public class RolesVO {
@NotNull(groups={ValidationGroup.Update.class})
private Long roleSeq;
@NotBlank(groups={ValidationGroup.Insert.class, ValidationGroup.Update.class})
private String roleId;
@NotBlank(groups={ValidationGroup.Insert.class, ValidationGroup.Update.class})
private String roleName;
private String roleComment;
private String regUserId;
private Date regDate;
private String modUserId;
private Date modDate;
}
Controller 에서 Vaild 처리
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity add(@RequestBody @Validated(ValidationGroup.Insert.class) RolesVO vo, BindingResult result) throws Exception {
if(result.hasErrors()){
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setMessage("Wrong request!");
errorResponse.setCode("bad.request");
return new ResponseEntity(errorResponse, HttpStatus.BAD_REQUEST);
}
return new ResponseEntity(modelMapper.map(service.addtRoles(vo), RolesVO.class), HttpStatus.CREATED);
}
/ validation / 사이에 보이는 값은 대부분 중복 처리가 된다.
이 경우 중복된 코드가 너무 많이 반복되어 다음과 같이 처리 하였다.
Aspect를 이용한 공통 validat 처리
ValidCheckingInterceptor
@Aspect
@Component
public class ValidCheckingInterceptor {
@Around("execution(* kr.pe.lahuman.*.controller.*.add*(..)) or execution(* kr.pe.lahuman.*.controller.*.modify*(..))")
public Object anyMethod(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] objs = joinPoint.getArgs();
for(Object obj : objs){
if(obj instanceof BindingResult){
BindingResult result = (BindingResult)obj;
if(result.hasErrors()){
Map<String, Map<String, String>> userdata = new HashMap<String, Map<String,String>>();
Map<String, String> errors = new LinkedHashMap<String, String>();
for (FieldError error : result.getFieldErrors()) {
errors.put(error.getField(), error.getDefaultMessage());
}
userdata.put("userdata", errors);
return new ResponseEntity(userdata, HttpStatus.BAD_REQUEST);
}
}
}
return joinPoint.proceed(joinPoint.getArgs());
}
}
Around 어노테이션에서 add와 modify로 시작되는 메소드 중 인자로 BindingResult 가 있을 경우 유효성 체크를 하여 에러가 있을 경우 문제 필드와 기본 메시지를 Map 형식으로 return 한다.
변경후 Controller에서 Vaild 제거 된 소스
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity add(@RequestBody @Validated(ValidationGroup.Insert.class) RolesVO vo, BindingResult result) throws Exception {
return new ResponseEntity(modelMapper.map(service.addtRoles(vo), RolesVO.class), HttpStatus.CREATED);
}
반복해서 작성 되었던 유효성 처리가 제거 되었다. 이후 Vaild 관련 처리는 ValidCheckingInterceptor에서만 진행 된다.
MD FILE :
Aspect_BindingResult.md