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; }
0 comments:
Post a Comment