2016-07-22 11 views
7

Mam kontroler odpoczynku, który wygląda tak:Java Instrukcja Walidacja po Argument Resolver

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

Klasa Payload wygląda następująco:

@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>(); 
} 

A ArgumentResolver wygląda następująco:

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; 
    } 
} 

Obecnie zajmuje to około 95% tego, co chcę zrobić. Pomyślnie pobiera wszystkie elementy z nagłówka i treści żądania i tworzy obiekt Payload. Ale po utworzeniu obiektu chcę uruchomić walidacje opisane w klasie Payload, takie jak NotNull, NotEmpty lub mój walidator klienta OneOrTheOther.

Zrobiłem kilka kopać wokół i znalazłem kilka artykułów stos here i here. Nie wiem, jak zaimplementować pierwszy, a drugi wydaje się zbyt skomplikowany i kłopotliwy, więc nie chcę tak naprawdę iść tą drogą. Wygląda na to, że używanie metody validateIfApplicable jest drogą, ale jak nazwać to w moim kontekście?

+0

proszę zobaczyć następujące http: // stackoverflow.com/questions/18091936/spring-mvc-valid-validation-with-custom-handlermethodargumentresolver?noredirect=1&lq=1 –

+0

Może możesz użyć walidacji JSR-303 Spring3, która jest łatwiejsza do spełnienia Twoich wymagań, a ArgumentResolver to nie jest konieczne. – TTCC

Odpowiedz

2

Możesz dodać instancję SmartValidator do swojej klasy. Wystarczy dodać:

@Autowired 
SmartValidator payloadValidator; 

Po wstrzyknięciu wystarczy wywołać metodę sprawdzania poprawności, przekazując swój komponent bean i listę błędów.

Dla porównania:

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

Oznacza to chcesz te validations być uruchomiony tuż po utworzeniu obiektu. Jeśli tak jest, to możesz stworzyć @Pointcut do metody, która zwraca swój obiekt, a które nazywamy walidacji chcesz @AfterReturning (powraca methodthat object)

 @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; 
    } 
Powiązane problemy