No exemplo a seguir, o ScriptFile
parâmetro é marcado com uma @Valid
anotação.
O que a @Valid
anotação faz?
@RequestMapping(value = "/scriptfile", method = RequestMethod.POST)
public String create(@Valid ScriptFile scriptFile, BindingResult result, ModelMap modelMap) {
if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");
if (result.hasErrors()) {
modelMap.addAttribute("scriptFile", scriptFile);
modelMap.addAttribute("showcases", ShowCase.findAllShowCases());
return "scriptfile/create";
}
scriptFile.persist();
return "redirect:/scriptfile/" + scriptFile.getId();
}
fonte
@Valid
emApplicationForm
parâmetro, mas, ainda validações foram disparados nadate
(Definir comonull
) campo. Por favor explique.IIRC @Valid não é uma anotação Spring, mas uma anotação JSR-303 (que é o padrão Bean Validation). O que ele faz é basicamente verificar se os dados que você envia ao método são válidos ou não (isso validará o scriptFile para você).
fonte
@Valid
em si não tem nada a ver com a primavera. Faz parte da especificação do Bean Validation (há vários deles, o último sendo JSR 380 no segundo semestre de 2017), mas@Valid
é muito antigo e deriva totalmente do JSR 303.Como todos sabemos, Spring é muito bom em fornecer integração com todos os diferentes JSRs e bibliotecas java em geral (pense em JPA, JTA, Caching, etc.) e, claro, esses caras cuidaram da validação também. Um dos principais componentes que facilita isso é MethodValidationPostProcessor .
Tentar responder à sua pergunta -
@Valid
é muito útil para a chamada validação em cascata, quando você deseja validar um gráfico complexo e não apenas os elementos de nível superior de um objeto. Cada vez que você quer ir mais fundo, você tem que usar@Valid
. Isso é o que a JSR determina. O Spring obedecerá a isso com alguns pequenos desvios (por exemplo, tentei colocar em@Validated
vez de@Valid
no método RestController e a validação funciona, mas o mesmo não se aplicará a um bean de "serviço" regular).fonte
ScriptFile scriptFile
.public String create(@Valid @NotNull ScriptFile scriptFile, BindingResult result, ModelMap modelMap) { if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");
Eu acho que esta
@NotNull
anotação é válida, portanto, se a condição não for necessária.fonte
Apenas adicionando à resposta acima, em um aplicativo da web
@valid
é usado onde o bean a ser validado também é anotado com anotações de validação@NotNull
, por exemplo ,@Email
(anotação de hibernação) para que ao obter a entrada do usuário os valores possam ser validados e o resultado da ligação terá a validação resultados.bindingResult.hasErrors()
dirá se alguma validação falhou.fonte
Outro aspecto útil do @Valid não mencionado acima é que (ou seja: usando o Postman para testar um endpoint) @Valid formatará a saída de uma chamada REST incorreta em JSON formatado ao invés de um blob de texto dificilmente legível. Isso é muito útil se você estiver criando uma API consumível comercialmente para seus usuários.
fonte
Acho que sei para onde vai sua pergunta. E como essa pergunta é a que aparece nos principais resultados de pesquisa do Google, posso dar uma resposta simples sobre o que a anotação @Valid faz.
Vou apresentar 3 cenários de como usei @Valid
Modelo:
public class Employee{ private String name; @NotNull(message="cannot be null") @Size(min=1, message="cannot be blank") private String lastName; //Getters and Setters for both fields. //... }
JSP:
... <form:form action="processForm" modelAttribute="employee"> <form:input type="text" path="name"/> <br> <form:input type="text" path="lastName"/> <form:errors path="lastName"/> <input type="submit" value="Submit"/> </form:form> ...
Controlador para o cenário 1:
@RequestMapping("processForm") public String processFormData(@Valid @ModelAttribute("employee") Employee employee){ return "employee-confirmation-page"; }
Neste cenário, depois de enviar seu formulário com um campo lastName vazio, você obterá uma página de erro, pois está aplicando regras de validação, mas não está lidando com isso de forma alguma.
Exemplo do referido erro: página de exceção
Controlador para o cenário 2:
@RequestMapping("processForm") public String processFormData(@Valid @ModelAttribute("employee") Employee employee, BindingResult bindingResult){ return bindingResult.hasErrors() ? "employee-form" : "employee-confirmation-page"; }
Nesse cenário, você está passando todos os resultados dessa validação para o bindingResult, então cabe a você decidir o que fazer com os resultados da validação desse formulário.
Controlador para o cenário 3:
@RequestMapping("processForm") public String processFormData(@Valid @ModelAttribute("employee") Employee employee){ return "employee-confirmation-page"; } @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Map<String, String> invalidFormProcessor(MethodArgumentNotValidException ex){ //Your mapping of the errors...etc }
Nesse cenário, você ainda não está lidando com os erros como no primeiro cenário, mas passa isso para outro método que cuidará da exceção de que @Valid dispara ao processar o modelo de formulário. Verifique isso para ver o que fazer com o mapeamento e tudo mais.
Resumindo : @Valid por si só não faz mais nada que acione a validação dos campos anotados JSR 303 de validação ( @NotNull, @Email, @Size, etc ... ), você ainda precisa especificar uma estratégia do que fazer com os resultados dessa validação.
Espero ter conseguido esclarecer algo para as pessoas que podem tropeçar com isso.
fonte