복붙노트

[SPRING] Spring MVC @PathVariable 값을 검증하는 방법은 무엇입니까?

SPRING

Spring MVC @PathVariable 값을 검증하는 방법은 무엇입니까?

스프링 MVC에서 구현 된 간단한 RESTful JSON API의 경우, Bean Validation (JSR-303)을 사용하여 핸들러 메소드에 전달 된 경로 변수의 유효성을 검사 할 수 있습니까?

예 :

 @RequestMapping(value = "/number/{customerNumber}")
 @ResponseBody
 public ResponseObject searchByNumber(@PathVariable("customerNumber") String customerNumber) {
 ...
 }

여기서는 Bean 유효성 검사를 사용하여 customerNumber 변수의 길이를 확인해야합니다. Spring MVC v3.x.x에서도 가능합니까? 그렇지 않은 경우이 유형의 유효성 검사에 가장 적합한 방법은 무엇입니까?

감사.

해결법

  1. ==============================

    1.Spring은 핸들러 메소드의 @PathVariable 주석 매개 변수에 @ javax.validation.Valid를 지원하지 않습니다. 개선 요청이 있었지만 아직 해결되지 않았습니다.

    Spring은 핸들러 메소드의 @PathVariable 주석 매개 변수에 @ javax.validation.Valid를 지원하지 않습니다. 개선 요청이 있었지만 아직 해결되지 않았습니다.

    최선의 방법은 핸들러 메서드 본문에서 사용자 정의 유효성 검사를 수행하거나 다른 대답에서 제안 된대로 org.springframework.validation.annotation.Validated를 사용하는 것입니다.

  2. ==============================

    2.다음과 같이 사용할 수 있습니다. 유효한 RequestParam 또는 PathVariable에 대해 유효성이 검사 된 org.springframework.validation.annotation.Validated를 사용하십시오.

    다음과 같이 사용할 수 있습니다. 유효한 RequestParam 또는 PathVariable에 대해 유효성이 검사 된 org.springframework.validation.annotation.Validated를 사용하십시오.

     *
     * Variant of JSR-303's {@link javax.validation.Valid}, supporting the
     * specification of validation groups. Designed for convenient use with
     * Spring's JSR-303 support but not JSR-303 specific.
     *
    

    step.1 init ValidationConfig

    @Configuration
    public class ValidationConfig {
        @Bean
        public MethodValidationPostProcessor methodValidationPostProcessor() {
            MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
            return processor;
        }
    }
    

    2 단계 : @Validated를 컨트롤러 핸들러 클래스에 추가하십시오.

    @RequestMapping(value = "poo/foo")
    @Validated
    public class FooController {
    ...
    }
    

    step.3 처리기 메서드에 유효성 검사기 추가 :

       @RequestMapping(value = "{id}", method = RequestMethod.DELETE)
       public ResponseEntity<Foo> delete(
               @PathVariable("id") @Size(min = 1) @CustomerValidator int id) throws RestException {
            // do something
            return new ResponseEntity(HttpStatus.OK);
        }
    

    마지막 단계. 문맥에 예외 해석자를 추가하십시오 :

    @Component
    public class BindExceptionResolver implements HandlerExceptionResolver {
    
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            if (ex.getClass().equals(BindException.class)) {
                BindException exception = (BindException) ex;
    
                List<FieldError> fieldErrors = exception.getFieldErrors();
                return new ModelAndView(new MappingJackson2JsonView(), buildErrorModel(request, response, fieldErrors));
            }
        }
    }
    
  3. ==============================

    3.@PathVariable은 읽을 수있는 메시지를 사용자에게 다시 보내기 위해 유효성이 검사되지 않습니다. 원칙으로서 pathVariable은 결코 무효가되어서는 안됩니다. pathVariable이 유효하지 않은 경우 그 이유는 다음과 같습니다.

    @PathVariable은 읽을 수있는 메시지를 사용자에게 다시 보내기 위해 유효성이 검사되지 않습니다. 원칙으로서 pathVariable은 결코 무효가되어서는 안됩니다. pathVariable이 유효하지 않은 경우 그 이유는 다음과 같습니다.

    두 경우 모두 예외적 인 거품을 놓아두기 만하면됩니다.     좋은 Spring ExceptionHandlers를 생성하기 위해     오류 페이지 또는 오류를 나타내는 의미있는 json 응답. 에서     이 결과를 얻으려면 사용자 정의 편집기를 사용하여 일부 유효성 검사를 수행 할 수 있습니다.

    CustomerNumber 클래스를 불변으로 만들 수 있습니다 (CharSequence를 구현하지 않아도되지만 기본적으로 String 인 것처럼 사용할 수 있음)

    public class CustomerNumber implements CharSequence {
    
        private String customerNumber;
    
        public CustomerNumber(String customerNumber) {
            this.customerNumber = customerNumber;
        }
    
        @Override
        public String toString() {
            return customerNumber == null ? null : customerNumber.toString();
        }
    
        @Override
        public int length() {
            return customerNumber.length();
        }
    
        @Override
        public char charAt(int index) {
            return customerNumber.charAt(index);
        }
    
        @Override
        public CharSequence subSequence(int start, int end) {
            return customerNumber.subSequence(start, end);
        }
    
        @Override
        public boolean equals(Object obj) {
            return customerNumber.equals(obj);
        }
    
        @Override
        public int hashCode() {
            return customerNumber.hashCode();
        }
    }
    

    유효성 검사 논리를 구현하는 편집기를 만듭니다 (이 경우에는 공백과 고정 길이가 없습니다)

    public class CustomerNumberEditor extends PropertyEditorSupport {
    
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
    
            if (StringUtils.hasText(text) && !StringUtils.containsWhitespace(text) && text.length() == YOUR_LENGTH) {
                setValue(new CustomerNumber(text));
            } else {
                throw new IllegalArgumentException();
                // you could also subclass and throw IllegalArgumentException
                // in order to manage a more detailed error message
            }
        }
    
        @Override
        public String getAsText() {
            return ((CustomerNumber) this.getValue()).toString();
        }
    }
    

    컨트롤러에 편집기 등록

    @InitBinder
    public void initBinder(WebDataBinder binder) {
    
        binder.registerCustomEditor(CustomerNumber.class, new CustomerNumberEditor());
        // ... other editors
    }
    

    String 대신 CustomerNumber를 수락하는 컨트롤러 메서드의 서명 변경 (ResponseObject가 무엇이든간에 ...)

    @RequestMapping(value = "/number/{customerNumber}")
    @ResponseBody
    public ResponseObject searchByNumber(@PathVariable("customerNumber") CustomerNumber customerNumber) {
        ...
    }
    
  4. ==============================

    4.해결책은 간단합니다.

    해결책은 간단합니다.

    @GetMapping(value = {"/", "/{hash:[a-fA-F0-9]{40}}"})
    public String request(@PathVariable(value = "hash", required = false) String historyHash)
    {
        // Accepted requests: either "/" or "/{40 character long hash}"
    }
    

    그리고 예, 경로 변수는 모든 사용자 입력과 마찬가지로 유효성이 검사됩니다.

  5. ==============================

    5.경로 변수는 시스템의 빈과 링크 될 수 없습니다. JSR-303 주석으로 주석을 달기를 원하십니까? 경로 변수의 유효성을 검사하려면이 방법을 사용해야합니다. @ 3Vvariable url on spring 3 mvc

    경로 변수는 시스템의 빈과 링크 될 수 없습니다. JSR-303 주석으로 주석을 달기를 원하십니까? 경로 변수의 유효성을 검사하려면이 방법을 사용해야합니다. @ 3Vvariable url on spring 3 mvc

  6. from https://stackoverflow.com/questions/19419234/how-to-validate-spring-mvc-pathvariable-values by cc-by-sa and MIT license