Multiple Use of validations in Spring Boot - spring-boot

I have an API with validation on it.
public class ModelVo {
#NotBlank(message = "...")
private String name;
#Pattern(regex="...", message = "...")
private String lastName;
...
}
I use of it
#PostMapping("/path1")
public ResponseEntity<RestResponse<Object>> create(#Valid #RequestBody ModelVo modelvo){
Now I want use of this validation for other method( for instance update API) again but I don't like #Pattern annotation on lastName fild work for second method. Is it possible?

Assuming that for create() you want to validate lastName with #Pattern but for update() you don't want to validate lastName you can achieve this with validation groups.
Your Controller:
#PostMapping("/path1")
public ResponseEntity<RestResponse<Object>> create(#Validated #RequestBody
ModelVo modelvo){
#PutMapping("/path1")
public ResponseEntity<RestResponse<Object>> update(#Validated(BasicInfo.class) #RequestBody
ModelVo modelvo){
Your Model class:
public class ModelVo {
#NotBlank(message = "...", groups = BasicInfo.class)
private String name;
#Pattern(regex="...", message = "...")
private String lastName;
}
You also need to create the BasicInfo class but that has nothing special.
You may get more information from the following links:
https://www.baeldung.com/spring-valid-vs-validated
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/annotation/Validated.html

Related

Form validation in thymeleaf by Springboot

I am new to the Springboot and Thymeleaf, I am creating a web where i am using form validation where I am trying to validate fields from an entity class to validate non empty fields.
import javax.validation.constraints.NotBlank;
public class Student {
#NotBlank(message = "Name required")
public String name;
#NotBlank(message = "email required")
public String email;
#NotBlank(message = "address required")
public String address;
#NotBlank(message = "username required")
public String username;
#NotBlank(message = "password required")
public String password;
'''
constructor
getter and setter
'''
}
It is not showing error in my html file, showing error on server.
If any one has any idea please help me.
In order this to work add #valid annotation next to #ModelAttribute("student").
public String addUser(#Valid #ModelAttribute("student") Student student, BindingResult result, Model model){
And also try adding #NotEmpty above the field of Student entity. #NotEmpty will check if the object has empty strings.
Try this,
public String addUser(#Valid #ModelAttribute("student") Student student, Model model){
...
}
Also, add #NotNull on entity attributes and check once.
Try out this:
public String addUser(#Valid #ModelAttribute("student") Student student, BindingResult result, Model model){
Also, add #NotNull on entity attributes and check once.

Spring MVC Based Rest Services Validations for request body

I have Rest Controller in my application which has the code snippet like below:-
#RestController
#RequestMapping("/api/v1/user")
public class UserRestControllerV1 {
#PostMapping("")
public Response registerUser(#RequestBody #Valid final Request<UserDto> request,
final HttpServletRequest httpServletRequest,
BindingResult result){
Response response = new Response(request);
if(result.hasErrors()){
response.setData(new String("Error"));
}else {
response.setData(new String("Test"));
}
return response;
}
The Request Class:-
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Request<T> {
#JsonProperty(value = "co-relation-id")
private String coRelationID;
#NotNull(message = "The request body should be present")
private T data;
/*
..... various other fields
Getters / Setters
*/
}
The UserDto Class :-
public class UserDto {
#NotNull(message = "The username should not be null")
private String username;
#NotNull(message = "The password should not be null")
#JsonIgnore
private String password;
/*
..... various other fields
Getters / Setters
*/
}
Issue : I am having issues with my validations here. The field private T data in the request class gets validated but the fields inside T - in the case UserDto are not getting validated.
So I need to know the approach or code snippet to achieve this.
I have tried configuring the hibernate validator bean in the configuration but it is of no help in the scenario
#Valid constraint will instruct the Bean Validator to delve to the type of its applied property and validate all constraints found there.
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Request<T> {
#JsonProperty(value = "co-relation-id")
private String coRelationID;
//#NotNull(message = "The request body should be present")
#Valid
private T data;
/*
..... various other fields
Getters / Setters
*/
}

How to control JSON serialization result from same POJO?

I have a Spring Boot based application with Jackson for JSON serialization/deserizalization and JodaTime for LocalDate object.
I have a User class :
public class User {
private String firstname;
private String lastname;
private String email;
private LocalDate birthday;
// constructor, getter, setter...
}
I have two webservices which don't expose same fields.
For example:
WS1 will expose all fields and translate birthday in the "yyyy-MM-dd" format;
WS2 will expose only firstname, lastname and birthday fields and translate birthday in the "yyyy/MM/dd" format.
It will give me something like this:
public class View {
public interface Default {}
public interface All extends Default {}
}
public class User {
#JsonView(View.Default.class)
private String firstname;
#JsonView(View.Default.class)
private String lastname;
#JsonView(View.All.class)
private String email;
#JsonView(View.Default.class)
private LocalDate birthday;
}
#RestController
public class UserController {
#RequestMapping("/ws1/user")
#JsonView(View.All.class)
public User userSeenByWS1() {
return new User("john", "doe", "john.doe#unknown.com", LocalDate.now());
/*
Must return {"firstname":"john","lastname":"doe","email":"john.doe#unknown.com","birthday":"2017-07-27"}
*/
}
#RequestMapping("/ws2/user")
#JsonView(View.Default.class)
public User userSeenByWS2() {
return new User("john", "doe", "john.doe#unknown.com", LocalDate.now());
/*
Must return {"firstname":"john","lastname":"doe","birthday":"2017/07/27"}
*/
}
}
For now, I know that I can control fields serialization with #JsonView annotation and I can create two different ObjectMapper to control LocalDate serialization. But I don't know how to pass to the #JsonView the well defined objectMapper for each webservice.
I don't want to create 2 DTOs which represent each view of my User class. I want something that I can configure via annotation.

javax.validation getting ignore from jersey

I am trying to use Jersey to get JSON request from the user to create vendor
#POST
#Produces({APPLICATION_JSON})
#Consumes({APPLICATION_JSON})
#Path("create")
public Response create(VendorTO vendorTO) throws Exception {
But before it converts in vendorTO object I want to validate it with javax.validation
I have added constraints in my pojo like this
{#JsonSerialize(include=Inclusion.NON_NULL)
public class VendorTO {
#NotNull
private Integer userId;
#Size(min = 2)
private String vendorName;
private String address1;
private String address2;
private String city;
private String state;
private String country;
private String email;
private String phone;
}
but it doesnt seems to be working. Can anyone help ?
You need to tell the framework that the parameter should be #Validated:
#POST
#Produces({APPLICATION_JSON})
#Consumes({APPLICATION_JSON})
#Path("create")
public Response create(#Valid VendorTO vendorTO) {
// ...
}
At this point, it appears Jersey does not support JSR 303 natively. You might have to write some ResourceFilters and handle the validation manually.

How to avoid binding of some fields?

Using the validation from PlayFramework and the data binding, is it possible, via (maybe) a decorator, to avoid binding some fields?
For example, I have this model :
class User extends Model {
#Required
#Email
public String email;
// I'd like to avoid setting this
public String password;
}
and in my model :
Store store = new Store();
Binder.bindBean(params.getRootParamNode(), store, null);
validation.valid(store);
If the user POST email AND password, password will be also set, but I don't want to.
How can I do that?
If you don't want to persist the data, but you want it to be bound as part of the automatic binding, then you can use the #Transient annotation...
Example
class User extends Model {
#Required
#Email
public String email;
// I'd like to avoid setting this
#Transient
public String password;
}
If you don't want it to be bound at all, then use the NoBinding annotation
#play.data.binding.NoBinding
Example
public class User extends Model {
#NoBinding("profile") public boolean isAdmin;
#As("dd, MM yyyy") Date birthDate;
public String name;
}

Resources