Monday, August 1, 2016

Java Manual Validation after Argument Resolver

Leave a Comment

I have a rest controller that looks like this:

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

The Payload class looks like this:

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

And the ArgumentResolver looks like this:

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

Currently this does about 95% of what I want it to do. It successfully retrieves all the items from the header and request body and creates a Payload object. But after creating the object I want to run the validations annotated in the Payload class like NotNull, NotEmpty or my customer validator OneOrTheOther.

I did some digging around and found a couple stack articles here and here. I don't know how to implement the first one and the second one seems overly complicated and cumbersome so I don't want to really go that route. It seems like using the validateIfApplicable method is the way to go but how would I call it in my context?

2 Answers

Answers 1

You could add a SmartValidator instance in your class. Just add:

@Autowired SmartValidator payloadValidator; 

Once injected, you just have to call the validate method on it, passing your bean and the list of errors.

For reference:

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

Answers 2

It means you want those validations to be run right after the creation of object. If this is the case then you can create the @Pointcut to the method which returns your Object,and which will call the validations you want @AfterReturning(methodthat returns 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;      } 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment