Skip to content

Commit 936a259

Browse files
authored
Bael 6906 (#16997)
* spring validator interface * added mockmvc * change file name * change file name
1 parent 7bfea36 commit 936a259

File tree

6 files changed

+261
-0
lines changed

6 files changed

+261
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.baeldung.springvalidator;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.validation.Validator;
6+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7+
8+
@Configuration
9+
public class AppConfig implements WebMvcConfigurer {
10+
@Bean
11+
public UserValidator userValidator() {
12+
return new UserValidator();
13+
}
14+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.baeldung.springvalidator;
2+
3+
public class User {
4+
private String name;
5+
private String email;
6+
7+
private int age;
8+
9+
public User() {
10+
}
11+
12+
public User(String name, String emailmail, int age) {
13+
this.name = name;
14+
this.email = email;
15+
this.age = age;
16+
}
17+
18+
// Getters and Setters
19+
public String getName() {
20+
return name;
21+
}
22+
23+
public void setName(String name) {
24+
this.name = name;
25+
}
26+
27+
public String getEmail() {
28+
return email;
29+
}
30+
31+
public void setEmail(String email) {
32+
this.email = email;
33+
}
34+
35+
public int getAge() {
36+
return age;
37+
}
38+
39+
public void setAge(int age) {
40+
this.age = age;
41+
}
42+
43+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.baeldung.springvalidator;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
import com.baeldung.spring.servicevalidation.SpringServiceLayerValidationApp;
7+
8+
@SpringBootApplication
9+
public class UserApplication {
10+
public static void main(String[] args) {
11+
SpringApplication.run(UserApplication.class, args);
12+
}
13+
14+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.baeldung.springvalidator;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.http.ResponseEntity;
5+
import org.springframework.validation.BeanPropertyBindingResult;
6+
import org.springframework.validation.Errors;
7+
import org.springframework.web.bind.annotation.PathVariable;
8+
import org.springframework.web.bind.annotation.PostMapping;
9+
import org.springframework.web.bind.annotation.PutMapping;
10+
import org.springframework.web.bind.annotation.RequestBody;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
import org.springframework.web.bind.annotation.RestController;
13+
14+
@RestController
15+
@RequestMapping("/api/users")
16+
public class UserController {
17+
@Autowired
18+
private UserValidator userValidator;
19+
20+
@PostMapping
21+
public ResponseEntity<?> createUser(@RequestBody User user) {
22+
Errors errors = new BeanPropertyBindingResult(user, "user");
23+
userValidator.validate(user, errors, "create");
24+
if (errors.hasErrors()) {
25+
return ResponseEntity.badRequest().body(errors.getAllErrors());
26+
}
27+
// Save the user object to the database
28+
return ResponseEntity.ok("User created successfully!");
29+
}
30+
31+
@PutMapping("/{id}")
32+
public ResponseEntity<?> updateUser(@PathVariable Long id, @RequestBody User user) {
33+
Errors errors = new BeanPropertyBindingResult(user, "user");
34+
userValidator.validate(user, errors, "update");
35+
if (errors.hasErrors()) {
36+
return ResponseEntity.badRequest().body(errors.getAllErrors());
37+
}
38+
// Update the user object in the database
39+
return ResponseEntity.ok("User updated successfully!");
40+
}
41+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.baeldung.springvalidator;
2+
3+
import org.springframework.util.StringUtils;
4+
import org.springframework.validation.Errors;
5+
import org.springframework.validation.Validator;
6+
7+
8+
public class UserValidator implements Validator {
9+
@Override
10+
public boolean supports(Class<?> clazz) {
11+
return User.class.isAssignableFrom(clazz);
12+
}
13+
14+
@Override
15+
public void validate(Object target, Errors errors) {
16+
User user = (User) target;
17+
if (StringUtils.isEmpty(user.getName())) {
18+
errors.rejectValue("name", "name.required");
19+
}
20+
if (StringUtils.isEmpty(user.getEmail())) {
21+
errors.rejectValue("email", "email.required");
22+
}
23+
// Add more validation rules as needed
24+
}
25+
26+
public void validate(Object target, Errors errors, Object... validationHints) {
27+
User user = (User) target;
28+
if (validationHints.length > 0) {
29+
if (validationHints[0] == "create") {
30+
if (StringUtils.isEmpty(user.getName())) {
31+
errors.rejectValue("name", "name.required","Name cannot be empty");
32+
}
33+
if (StringUtils.isEmpty(user.getEmail())) {
34+
errors.rejectValue("email", "email.required" , "Invalid email format");
35+
}
36+
if (user.getAge() < 18 || user.getAge() > 65) {
37+
errors.rejectValue("age", "user.age.outOfRange", new Object[]{18, 65}, "Age must be between 18 and 65");
38+
}
39+
} else if (validationHints[0] == "update") {
40+
// Perform update-specific validation
41+
if (StringUtils.isEmpty(user.getName()) && StringUtils.isEmpty(user.getEmail())) {
42+
errors.rejectValue("name", "name.or.email.required", "Name or email cannot be empty");
43+
}
44+
}
45+
} else {
46+
// Perform default validation
47+
if (StringUtils.isEmpty(user.getName())) {
48+
errors.rejectValue("name", "name.required");
49+
}
50+
if (StringUtils.isEmpty(user.getEmail())) {
51+
errors.rejectValue("email", "email.required");
52+
}
53+
}
54+
}
55+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package com.baeldung.springvalidator;
2+
3+
import static org.mockito.Mockito.*;
4+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
5+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
6+
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import org.junit.jupiter.api.BeforeEach;
9+
import org.junit.jupiter.api.Test;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
12+
import org.springframework.boot.test.mock.mockito.MockBean;
13+
import org.springframework.http.MediaType;
14+
import org.springframework.test.web.servlet.MockMvc;
15+
import org.springframework.validation.Errors;
16+
17+
@WebMvcTest(UserController.class)
18+
public class UserControllerIntegrationTest {
19+
20+
@Autowired
21+
private MockMvc mockMvc;
22+
23+
@MockBean
24+
private UserValidator userValidator;
25+
26+
private ObjectMapper objectMapper;
27+
28+
@BeforeEach
29+
void setUp() {
30+
objectMapper = new ObjectMapper();
31+
}
32+
33+
@Test
34+
void givenValidUser_whenCreateUser_thenReturnsOk() throws Exception {
35+
User validUser = new User("John Doe", "[email protected]", 30);
36+
37+
doNothing().when(userValidator).validate(any(), any(), eq("create"));
38+
39+
mockMvc.perform(post("/api/users")
40+
.contentType(MediaType.APPLICATION_JSON)
41+
.content(objectMapper.writeValueAsString(validUser)))
42+
.andExpect(status().isOk())
43+
.andExpect(content().string("User created successfully!"));
44+
}
45+
46+
@Test
47+
void givenInvalidUser_whenCreateUser_thenReturnsBadRequest() throws Exception {
48+
User invalidUser = new User("", "", 30);
49+
50+
doAnswer(invocation -> {
51+
Errors errors = invocation.getArgument(1);
52+
errors.rejectValue("name", "name.required", "Name cannot be empty");
53+
errors.rejectValue("email", "email.required", "Invalid email format");
54+
return null;
55+
}).when(userValidator).validate(any(), any(), eq("create"));
56+
57+
mockMvc.perform(post("/api/users")
58+
.contentType(MediaType.APPLICATION_JSON)
59+
.content(objectMapper.writeValueAsString(invalidUser)))
60+
.andExpect(status().isBadRequest())
61+
.andExpect(jsonPath("$[0].defaultMessage").value("Name cannot be empty"))
62+
.andExpect(jsonPath("$[1].defaultMessage").value("Invalid email format"));
63+
}
64+
65+
@Test
66+
void givenValidUser_whenUpdateUser_thenReturnsOk() throws Exception {
67+
User validUser = new User("John Doe", "[email protected]", 30);
68+
69+
doNothing().when(userValidator).validate(any(), any(), eq("update"));
70+
71+
mockMvc.perform(put("/api/users/1")
72+
.contentType(MediaType.APPLICATION_JSON)
73+
.content(objectMapper.writeValueAsString(validUser)))
74+
.andExpect(status().isOk())
75+
.andExpect(content().string("User updated successfully!"));
76+
}
77+
78+
@Test
79+
void givenInvalidUser_whenUpdateUser_thenReturnsBadRequest() throws Exception {
80+
User invalidUser = new User("", "", 30);
81+
82+
doAnswer(invocation -> {
83+
Errors errors = invocation.getArgument(1);
84+
errors.rejectValue("name", "name.or.email.required", "Name or email cannot be empty");
85+
return null;
86+
}).when(userValidator).validate(any(), any(), eq("update"));
87+
88+
mockMvc.perform(put("/api/users/1")
89+
.contentType(MediaType.APPLICATION_JSON)
90+
.content(objectMapper.writeValueAsString(invalidUser)))
91+
.andExpect(status().isBadRequest())
92+
.andExpect(jsonPath("$[0].defaultMessage").value("Name or email cannot be empty"));
93+
}
94+
}

0 commit comments

Comments
 (0)