Does #Valid work without #Validated on #RestController? - spring

In following blog entry.
https://www.baeldung.com/spring-boot-bean-validation
The author mentioned about how Spring Boot works with #Valid annotation.
#RestController
public class UserController {
#PostMapping("/users")
ResponseEntity<String> addUser(#Valid #RequestBody User user) {
// persisting the user
return ResponseEntity.ok("User is valid");
}
// standard constructors / other methods
}
When Spring Boot finds an argument annotated with #Valid, it automatically bootstraps the default JSR 380 implementation — Hibernate Validator — and validates the argument.
Is it true that #Valid works as expected on #RestController without #Validated?
Then what kind of stereo types required to be explicitly annotated with #Validated?

Yes #Valid will work without #Validated in #RestController.
In Spring, we use JSR-303's #Valid annotation for method level
validation. Moreover, we also use it to mark a member attribute for
validation. However, this annotation doesn't support group validation.
Groups help to limit the constraints applied during validation. One
particular use case is UI wizards. Here, in the first step, we may
have a certain sub-group of fields. In the subsequent step, there may
be another group belonging to the same bean. Hence we need to apply
constraints on these limited fields in each step, but #Valid doesn't
support this. In this case, for group-level, we have to use Spring's
#Validated, which is a variant of this JSR-303's #Valid. This is used
at the method-level. And for marking member attributes, we continue to
use the #Valid annotation.
You can read more about this in this link.

Related

Spring boot: #Valid not working with #RequestHeader

I'm really struggling to combine #Valid with #RequestHeader.
Might this be not supported or is there a way to enable it? I couldn't find useful information about that...
When I annotate the whole controller with #Validated it works, so it is not a big issue. However, I feel like it should work with #Valid as well, so I wanted to know if I'm missing something here.
Code example:
#GetMapping("/validationControllerHeader")
public String validationControllerHeader(#Valid #RequestHeader #Pattern(regexp = "[a-z]{3}[0-9]+") String someheader) {
return someheader;
}
I'm using #Valid in the same test controller for query parameters and body validation too and there it works, so the issue is only present with headers.
Using spring boot 2.3.1.RELEASE
You are definitely supposed to use #Validated in your controller class, as it indicates that the validation is meant to be performed in that class. From the documentation:
To be eligible for Spring-driven method validation, all target classes need to be annotated with Spring’s #Validated annotation, which can optionally also declare the validation groups to use.
And, as you are using #Pattern (which is a Bean Validation annotation), you don't need #Valid.

Best way to provide validation to spring mvc & hibernate projects

I'm new to spring & hibernate, please suggest a best way to provide validation to spring mvc & hibernate projects. I tried hibernate validator but i don't know how to use it when there is relationship(like #OneToOne) between entity objects. If there is any examples, please provide the link.
Your #OneToOne relationship is not clear enough. Could you please give a concrete scenario?
In Spring MVC you have three types of validations:
JSR-303 bean validation (hibernate validator)
Custom validation
Spring validation
JSR-303 works great for simple validations on single fields. You have standard annotations like (#Max, #Min, #NULL, #Pattern, etc.). It does not seem enough for you in this case.
Custom validation is used in a more complex scenario. For instance, what if we need to validate that the newly added product ID is not the same as any of the existing product IDs?
Spring validation represents cross-field validation.
For instance, it's used when we want to compare two or more fields to see if
their values can be considered as valid when combined.
you can use spring validation method.
using valid annotion in controller classes infront of modelattribute annotaion.
then you can use validaions in the model class.
below is an example for controller and bean classes.
this is a many to one configuration inside a bean class:
#ManyToOne(targetEntity = UserType.class)
#JoinColumn(name = "user_type", referencedColumnName = "id")
#NotNull
private UserType userTypeTb;
this is a method inside controller class with valid and modelattribute annotaion:
public ModelAndView home(#Valid #ModelAttribute("user") User user, BindingResult result,
HttpServletRequest request) {
//
//
}

Will the #Validated annotation in the DAO Interface help at all?

I have seen a lot of #Validated annotations in the DAOs interface that I didn't write. For example:
#Validated
public interface CompanyDAO extends BaseDAO<Company> {
public List<Company> list();
What behaviour should I expect from this:
Validating all the objects passed to the DAO before saving them into the database?
Validating all the objects that the DAO retrieves from the database?
Both of them?
Nothing at all. This annotation should not be placed in DAO interfaces.
Just a few pointers which you might not be aware of:
8.8 Spring Validation of 8. Validation, Data Binding, and Type Conversion in the manual specifies that
In order to be eligible for Spring-driven method validation, all target classes need to be annotated with Spring’s #Validated annotation, optionally declaring the validation groups to use. Check out the MethodValidationPostProcessor javadocs for setup details with Hibernate Validator and Bean Validation 1.1 providers.
MethodValidationPostProcessor says
Applicable methods have JSR-303 constraint annotations on their parameters and/or on their return value (in the latter case specified at the method level, typically as inline annotation), e.g.:
public #NotNull Object myValidMethod(#NotNull String arg1, #Max(10) int arg2)
Target classes with such annotated methods need to be annotated with Spring's Validated annotation at the type level, for their methods to be searched for inline constraint annotations. Validation groups can be specified through #Validated as well. By default, JSR-303 will validate against its default group only.
So, maybe the answer to your question
What behaviour should I expect
is: Whatever constraints are given in the code.

Spring annotations #ModelAttribute and #Valid

What are the advantages of using #ModelAttribute and #Valid?
Which are the differences?
Is it possible to use them together?
#ModelAttribute is used to map/bind a a method parameter or method return type to a named model attribute. See #ModelAttributes JavaDoc. This is a Spring annotation.
#Valid is an annotation that marks an object for JSR-303 bean validation. See #Valids JavaDoc. It is part of JavaEE 6, but I think Hibernate has an earlier implementation that most people use instead.
The advantage of using #ModelAttribute is that you can map a form's inputs to a bean. The advantage of #Valid is that you can utilize JSR-303 bean validation to ensure that the bean that is made is validated against some set of rules.
Yes you can use #ModelAttribute and #Valid together.
The best way to transfer data from a form (sic View) to the a Model object is to follow the typical/traditional MVC design pattern using Spring. My personal preferred way is to have a form in a JSP with Spring JSTL <form:*> tags, with a modelAttribute set. On the Controller, have a handler to accept the POST from the form that has a matching #ModelAttribute that is a bean that represents the form's input. I would then pass that "Form Bean" to a service layer to do some things, including translating the "Form Bean" into any models if needed (not necessary if the form is creating your model objects directly) and saving/updating/etc via a DAO. This is but one way to do things, but it's probably the bulk of what I do with Spring in my day-to-day job.
I would highly recommend reading the Spring reference materials and following the tutorials. The reference materials are very well written, easy to follow, and includes lots of examples on the various ways you can do things in Spring, and there are usually quite a few options on how you do things in Spring.
please check the below part fro spring reference documentation:
In addition to data binding you can also invoke validation using your own custom validator passing the same BindingResult that was used to record data binding errors. That allows for data binding and validation errors to be accumulated in one place and subsequently reported back to the user:
#RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(#ModelAttribute("pet") Pet pet, BindingResult result) {
new PetValidator().validate(pet, result);
if (result.hasErrors()) {
return "petForm";
}
// ...
}
Or you can have validation invoked automatically by adding the JSR-303 #Valid annotation:
#RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(#Valid #ModelAttribute("pet") Pet pet, BindingResult result) {
if (result.hasErrors()) {
return "petForm";
}
// ...
}

Bean Validation for POST requisition in JAX-RS with Jersey implementation

I'm using the Jersey implementation for JAX-RS, and I was looking for an example where I can use the Bean Validation in POST requisitions. I have this operation, for example:
#POST
#Path("document/annotations/save")
#Produces("application/json")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Map<String, Object> saveAnnotation(
#FormParam("user") String userStr,
#FormParam("documentId") String documentId,
#FormParam("documentPage") Integer documentPage,
#FormParam("annotationContent") String annotationContent,
#FormParam("annotationId") Long annotationId,
#FormParam("isMobile") Boolean isMobile) { // the code... }
I wanna use validations constraints (#NotNull, #Pattern, etc) for each method param. I saw this doc where they're using the Seam Framework to do that.
Currently, I'm trying to use the javax.validation implementation to validate my requests, but it doesn't working.
Is there a way to use the JSR-303 specification with JAX-RS?
Tnks.
This is currently not possible using Jersey; one possible alternative is to write a customer resource filter and bind to the #NotNull, etc. annotations.
It would be simpler if it was encapsulated in a resource class because you could then bind to a #Valid annotation on your method and validate the bean in one shot.
Because JSR-303 is designed to deal with beans and not a collection of parameters then it ends up being very verbose when you try to bend it to your will.
IMHO it's better not to keep validation inside your class anyway and to either use the pipes and filters pattern, i.e. ContainerRequestFilter, or to use something like AspectJ as #Willy suggested.
It's possible. See docs for latest Jersey
https://jersey.java.net/documentation/latest/bean-validation.html#d0e9380
https://jersey.java.net/documentation/latest/bean-validation.html

Resources