2016-07-22 13 views
7

Tôi có một bộ điều khiển phần còn lại trông như thế này:Java Validation tay sau Argument Resolver

@RequestMapping(
     value = "/foo", 
     method = RequestMethod.POST) 
@ResponseBody 
public ResponseEntity<JsonNode> getFOOs(@Valid Payload payload) { 
    /** some code **/ 
} 

Lớp Payload trông như thế này:

@OneOrTheOther(first = "a", second = "b") 
public final class Payload { 
    private final String userName; 
    private final String a; 
    private final String b; 
    @NotNull 
    private final String c; 
    @NotEmtpy{message="At least 1 item"} 
    private List<String> names = new ArrayList<String>(); 
} 

Và ArgumentResolver trông như thế này:

public class PayloadArgumentResolver implements HandlerMethodArgumentResolver { 
    @Override 
    public boolean supportsParameter(MethodParameter methodParameter) { 
     return methodParameter.getParameterType().equals(Payload.class); 
    } 

    @Override 
    public Object resolveArgument(MethodParameter methodParameter, 
            ModelAndViewContainer modelAndViewContainer, 
            NativeWebRequest nativeWebRequest, 
            WebDataBinderFactory webDataBinderFactory) throws Exception { 
     if(supportsParameter(methodParameter)) { 
      HttpServletRequest requestHeader = nativeWebRequest.getNativeRequest(HttpServletRequest.class); 
      String userName = requestHeader.getHeader("userName"); 

      ObjectMapper mapper = new ObjectMapper(); 
      JsonNode requestBody = mapper.readTree(CharStreams.toString(requestHeader.getReader())); 

      JsonNode a = requestBody.path("a"); 
      String a = a.isMissingNode() ? null : a.asText(); 

      JsonNode b = requestBody.path("b"); 
      String b = b.isMissingNode() ? null : b.asText(); 

      JsonNode c = requestBody.path("c"); 
      String c = c.isMissingNode() ? null : c.asText(); 

      JavaType type = mapper.getTypeFactory().constructCollectionType(ArrayList.class, String.class); 
      List<String> ids 
        = requestBody.path("ids").isMissingNode() 
        ? null : mapper.readValue(requestBody.path("ids").toString(), type); 


      return new Payload(username, a, b, c, ids); 
     } 
     return null; 
    } 
} 

Hiện tại, điều này có nghĩa là khoảng 95% những gì tôi muốn. Nó lấy thành công tất cả các mục từ phần đầu và phần thân yêu cầu và tạo ra một đối tượng Payload. Nhưng sau khi tạo đối tượng, tôi muốn chạy các xác thực được chú thích trong lớp Payload như NotNull, NotEmpty hoặc trình xác thực khách hàng của mình OneOrTheOther.

Tôi đã thực hiện một số thao tác xung quanh và tìm thấy một số bài viết chồng herehere. Tôi không biết làm thế nào để thực hiện một trong những đầu tiên và thứ hai có vẻ quá phức tạp và rườm rà nên tôi không muốn thực sự đi con đường đó. Có vẻ như sử dụng phương pháp validateIfApplicable là cách để đi nhưng tôi sẽ gọi nó như thế nào trong ngữ cảnh của mình?

+0

Hãy xem sau http: // stackoverflow.com/questions/18091936/spring-mvc-valid-validation-with-custom-handlermethodargumentresolver?noredirect=1&lq=1 –

+0

Có lẽ bạn có thể sử dụng các xác thực JSR-303 của Spring3, dễ dàng hơn để đáp ứng nhu cầu của bạn, và ArgumentResolver không cần thiết. – TTCC

Trả lời

2

Bạn có thể thêm cá thể SmartValidator vào lớp học của mình. Chỉ cần thêm:

@Autowired 
SmartValidator payloadValidator; 

Sau khi được tiêm, bạn chỉ cần gọi phương thức xác thực trên đó, chuyển đậu và danh sách lỗi.

Để tham khảo:

SmartValidator: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/validation/SmartValidator.html

erros: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/validation/Errors.html

1

Nó có nghĩa là bạn muốn những kiểm chứng thực được chạy ngay sau khi việc tạo ra các đối tượng. Nếu đây là trường hợp sau đó bạn có thể tạo các @Pointcut cho phương thức trả về đối tượng của bạn, và đó sẽ gọi kiểm chứng thực bạn muốn @AfterReturning (lợi nhuận methodthat đối tượng)

 @Pointcut("execution(* YourClass.*(..))") 
    public void pointcut(){} 

    @AfterReturning("method that returns object") 
    public final class Payload { 
     private final String userName; 
     private final String a; 
     private final String b; 
    }