Java Manual Validation after Argument Resolver

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?


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


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;
     }
链接地址: http://www.djcxy.com/p/35460.html

上一篇: 虚拟调用基类方法

下一篇: 参数解析器之后的Java手动验证