ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TIP]Aspect 를 이용한 공통 BindingResult 처리 방법
    설치&설정 관련/Spring Framework 2016. 5. 24. 16:25

    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 {
            /* validation */
             if(result.hasErrors()){
                ErrorResponse errorResponse = new ErrorResponse();
                errorResponse.setMessage("Wrong request!");
                errorResponse.setCode("bad.request");
                return new ResponseEntity(errorResponse, HttpStatus.BAD_REQUEST);
            }
            /* validation */
            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



Designed by Tistory.