Skip to content

Commit d0bd323

Browse files
committed
validation feature:
i define validationUtils for implement any validation process and define validationHandler for manage validation request from validator, also define validator annotation for attach on any filed for validation. at the end i create validationValidator for wrap validation constraint and work with spring
1 parent 2767fa7 commit d0bd323

15 files changed

Lines changed: 523 additions & 75 deletions

File tree

pom.xml

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@
8383
<artifactId>spring-boot-starter-aop</artifactId>
8484
</dependency>
8585

86+
<!-- validation -->
87+
<dependency>
88+
<groupId>org.springframework.boot</groupId>
89+
<artifactId>spring-boot-starter-validation</artifactId>
90+
</dependency>
91+
8692
<!--use cache dependency -->
8793
<dependency>
8894
<groupId>org.springframework.boot</groupId>
@@ -105,6 +111,20 @@
105111
<version>${org.mapstruct.version}</version>
106112
</dependency>
107113

114+
<!-- Apache Commons is an Apache project focused on all aspects of reusable Java components -->
115+
<dependency>
116+
<groupId>org.apache.commons</groupId>
117+
<artifactId>commons-lang3</artifactId>
118+
<version>3.11</version>
119+
</dependency>
120+
121+
<!-- lombok -->
122+
<dependency>
123+
<groupId>org.projectlombok</groupId>
124+
<artifactId>lombok</artifactId>
125+
<optional>true</optional>
126+
</dependency>
127+
108128
<dependency>
109129
<groupId>org.springframework.boot</groupId>
110130
<artifactId>spring-boot-starter-test</artifactId>
@@ -138,22 +158,22 @@
138158
<artifactId>mapstruct-processor</artifactId>
139159
<version>${org.mapstruct.version}</version>
140160
</path>
141-
<!-- <path>-->
142-
<!-- <groupId>org.projectlombok</groupId>-->
143-
<!-- <artifactId>lombok</artifactId>-->
144-
<!-- <version>${lombok.version}</version>-->
145-
<!-- </path>-->
146-
<!-- <dependency>-->
147-
<!-- <groupId>org.projectlombok</groupId>-->
148-
<!-- <artifactId>lombok-mapstruct-binding</artifactId>-->
149-
<!-- <version>0.2.0</version>-->
150-
<!-- </dependency>-->
161+
<path>
162+
<groupId>org.projectlombok</groupId>
163+
<artifactId>lombok</artifactId>
164+
<version>${lombok.version}</version>
165+
</path>
166+
<dependency>
167+
<groupId>org.projectlombok</groupId>
168+
<artifactId>lombok-mapstruct-binding</artifactId>
169+
<version>0.2.0</version>
170+
</dependency>
151171
</annotationProcessorPaths>
152-
<!-- <compilerArgs>-->
153-
<!-- <compilerArg>-->
154-
<!-- -Amapstruct.defaultComponentModel=spring-->
155-
<!-- </compilerArg>-->
156-
<!-- </compilerArgs>-->
172+
<compilerArgs>
173+
<compilerArg>
174+
-Amapstruct.defaultComponentModel=spring
175+
</compilerArg>
176+
</compilerArgs>
157177
</configuration>
158178
</plugin>
159179
</plugins>

src/main/java/ir/bigz/springbootreal/commons/generallog/AppLogAspect.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class AppLogAspect {
1919

2020
private final Logger LOG = LoggerFactory.getLogger(AppLogAspect.class);
2121

22-
@Before("ir.bigz.springbootreal.commons.generallog.CommonJoinPoint.ControllerExecution()")
22+
@Before("ir.bigz.springbootreal.commons.generallog.CommonJoinPoint.controllerExecution()")
2323
public void beforeCallControllerMethod(JoinPoint joinPoint){
2424
String methodName = joinPoint.getSignature().getName();
2525
Object[] args = joinPoint.getArgs();
@@ -28,7 +28,7 @@ public void beforeCallControllerMethod(JoinPoint joinPoint){
2828
methodName, reduce);
2929
}
3030

31-
@AfterReturning(value = "ir.bigz.springbootreal.commons.generallog.CommonJoinPoint.ControllerExecution()",
31+
@AfterReturning(value = "ir.bigz.springbootreal.commons.generallog.CommonJoinPoint.controllerExecution()",
3232
returning = "obj")
3333
public void afterReturningResponseOfControllerMethod(JoinPoint joinPoint, Object obj){
3434
String methodName = joinPoint.getSignature().getName();
@@ -37,7 +37,7 @@ public void afterReturningResponseOfControllerMethod(JoinPoint joinPoint, Object
3737
LOG.info("after method: {} | argument: {} | result: {}", methodName, reduce, ((ResponseEntity) obj).getBody());
3838
}
3939

40-
@AfterThrowing(pointcut = "execution(* ir.bigz.springbootreal.service.*.*(..))", throwing = "exception")
40+
@AfterThrowing(value = "ir.bigz.springbootreal.commons.generallog.CommonJoinPoint.serviceExecution()", throwing = "exception")
4141
public void logAfterThrowException(JoinPoint joinPoint, AppException exception){
4242
String methodName = joinPoint.getSignature().getName();
4343
LOG.info("exception method: {} | errorCode: {} | message: {}",

src/main/java/ir/bigz/springbootreal/commons/generallog/CommonJoinPoint.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,8 @@
55
public class CommonJoinPoint {
66

77
@Pointcut("execution(* ir.bigz.springbootreal.controller.*.*(..))")
8-
public void ControllerExecution(){};
8+
public void controllerExecution(){};
9+
10+
@Pointcut("execution(* ir.bigz.springbootreal.service.*.*(..))")
11+
public void serviceExecution(){};
912
}

src/main/java/ir/bigz/springbootreal/controller/SampleController.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.springframework.http.ResponseEntity;
88
import org.springframework.web.bind.annotation.*;
99

10+
import javax.validation.Valid;
1011
import java.util.List;
1112

1213
@RestController
@@ -29,7 +30,7 @@ public ResponseEntity<?> getUserById(@PathVariable("id") long id) {
2930

3031
@PostMapping(path = "/user/add", produces = MediaType.APPLICATION_JSON_VALUE)
3132
@ResponseStatus(HttpStatus.CREATED)
32-
public ResponseEntity<?> addUser(@RequestBody UserModel userModel) {
33+
public ResponseEntity<?> addUser(@Valid @RequestBody UserModel userModel) {
3334
UserModel userModelResult = userService.addUser(userModel);
3435
return ResponseEntity.ok(userModelResult);
3536
}

src/main/java/ir/bigz/springbootreal/dao/User.java

Lines changed: 88 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,59 +10,119 @@
1010
public class User implements Serializable {
1111

1212
@Id
13-
@GeneratedValue
13+
@GeneratedValue(strategy = GenerationType.AUTO)
1414
@Column(name = "user_id")
1515
private long id;
1616

17-
@Column(name = "name", nullable = false)
18-
private String name;
17+
@Column(name = "first_name", nullable = false)
18+
private String firstName;
1919

20-
@Column(name = "national_id", nullable = false, unique = true)
21-
private String nationalId;
20+
@Column(name = "last_name", nullable = false)
21+
private String lastName;
2222

23-
public long getId() {
24-
return id;
25-
}
26-
27-
public void setId(long id) {
28-
this.id = id;
29-
}
23+
@Column(name = "user_name", nullable = false)
24+
private String userName;
3025

31-
public String getName() {
32-
return name;
33-
}
26+
@Column(name = "national_code", nullable = false, unique = true)
27+
private String nationalCode;
3428

35-
public String getNationalId() {
36-
return nationalId;
37-
}
29+
@Column(name = "mobile")
30+
private String mobile;
3831

39-
public void setNationalId(String nationalId) {
40-
this.nationalId = nationalId;
41-
}
32+
@Column(name = "email")
33+
private String email;
4234

43-
public void setName(String name) {
44-
this.name = name;
45-
}
35+
@Column(name = "gender")
36+
private String gender;
4637

4738
@Override
4839
public boolean equals(Object o) {
4940
if (this == o) return true;
5041
if (o == null || getClass() != o.getClass()) return false;
5142
User user = (User) o;
52-
return nationalId.equals(user.nationalId);
43+
return nationalCode.equals(user.nationalCode);
5344
}
5445

5546
@Override
5647
public int hashCode() {
57-
return Objects.hash(nationalId);
48+
return Objects.hash(nationalCode);
5849
}
5950

6051
@Override
6152
public String toString() {
6253
return "User{" +
6354
"id=" + id +
64-
", name='" + name + '\'' +
65-
", nationalId='" + nationalId + '\'' +
55+
", firstName='" + firstName + '\'' +
56+
", lastName='" + lastName + '\'' +
57+
", userName='" + userName + '\'' +
58+
", nationalCode='" + nationalCode + '\'' +
59+
", mobile='" + mobile + '\'' +
60+
", email='" + email + '\'' +
61+
", gender='" + gender + '\'' +
6662
'}';
6763
}
64+
65+
public long getId() {
66+
return id;
67+
}
68+
69+
public void setId(long id) {
70+
this.id = id;
71+
}
72+
73+
public String getFirstName() {
74+
return firstName;
75+
}
76+
77+
public void setFirstName(String firstName) {
78+
this.firstName = firstName;
79+
}
80+
81+
public String getLastName() {
82+
return lastName;
83+
}
84+
85+
public void setLastName(String lastName) {
86+
this.lastName = lastName;
87+
}
88+
89+
public String getUserName() {
90+
return userName;
91+
}
92+
93+
public void setUserName(String userName) {
94+
this.userName = userName;
95+
}
96+
97+
public String getNationalCode() {
98+
return nationalCode;
99+
}
100+
101+
public void setNationalCode(String nationalCode) {
102+
this.nationalCode = nationalCode;
103+
}
104+
105+
public String getMobile() {
106+
return mobile;
107+
}
108+
109+
public void setMobile(String mobile) {
110+
this.mobile = mobile;
111+
}
112+
113+
public String getEmail() {
114+
return email;
115+
}
116+
117+
public void setEmail(String email) {
118+
this.email = email;
119+
}
120+
121+
public String getGender() {
122+
return gender;
123+
}
124+
125+
public void setGender(String gender) {
126+
this.gender = gender;
127+
}
68128
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package ir.bigz.springbootreal.exception.validation;
2+
3+
import org.springframework.http.HttpHeaders;
4+
import org.springframework.http.HttpStatus;
5+
import org.springframework.http.ResponseEntity;
6+
import org.springframework.validation.FieldError;
7+
import org.springframework.web.bind.MethodArgumentNotValidException;
8+
import org.springframework.web.bind.annotation.RestControllerAdvice;
9+
import org.springframework.web.context.request.WebRequest;
10+
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
11+
12+
import java.time.ZoneId;
13+
import java.time.ZonedDateTime;
14+
import java.time.format.DateTimeFormatter;
15+
import java.util.HashMap;
16+
import java.util.Map;
17+
18+
@RestControllerAdvice
19+
public class ErrorController extends ResponseEntityExceptionHandler {
20+
21+
@Override
22+
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
23+
HttpHeaders headers,
24+
HttpStatus status,
25+
WebRequest request) {
26+
27+
Map<String, String> errors = new HashMap<>();
28+
ex.getBindingResult().getAllErrors().forEach((error) -> {
29+
String fieldName = ((FieldError) error).getField();
30+
String errorMessage = error.getDefaultMessage();
31+
errors.put(fieldName, errorMessage);
32+
});
33+
34+
35+
36+
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponseModel.builder()
37+
.errors(errors)
38+
.timestamp(timeLog())
39+
.path(request.getDescription(false)).build());
40+
}
41+
42+
private String timeLog(){
43+
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd - HH:mm:ss z");
44+
return ZonedDateTime.now(ZoneId.of("Asia/Tehran")).format(formatter);
45+
}
46+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package ir.bigz.springbootreal.exception.validation;
2+
3+
import lombok.Builder;
4+
import lombok.Getter;
5+
6+
import java.util.Map;
7+
8+
@Getter
9+
@Builder
10+
public class ErrorResponseModel {
11+
12+
private final Map<String, String> errors;
13+
private final String timestamp;
14+
private final String path;
15+
}

src/main/java/ir/bigz/springbootreal/service/UserServiceImpl.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
import org.springframework.transaction.annotation.Propagation;
1515
import org.springframework.transaction.annotation.Transactional;
1616

17-
import java.util.List;
18-
import java.util.Objects;
19-
import java.util.Optional;
17+
import java.util.*;
2018
import java.util.stream.Collectors;
2119
import java.util.stream.Stream;
2220

@@ -53,16 +51,15 @@ public UserModel getUser(Long userId) {
5351
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
5452
public UserModel addUser(UserModel userModel) {
5553
try {
56-
if(userRepository.getUserWithNationalId(userModel.getNationalId()) == null){
54+
if(userRepository.getUserWithNationalId(userModel.getNationalCode()) == null){
5755
User user = userMapper.userModelToUser(userModel);
5856
return userMapper.userToUserModel(userRepository.insert(user));
5957
}
6058
throw new RuntimeException("user has already exist");
6159

6260
}catch (RuntimeException exception){
6361
throw AppException.newInstance(
64-
HttpErrorCode.ERR_10700,
65-
String.format("user has already existed with %s nationalId", userModel.getNationalId())
62+
HttpErrorCode.ERR_10700, String.format("user has already existed with %s nationalId", userModel.getNationalCode())
6663
);
6764
}
6865
}
@@ -118,11 +115,26 @@ public List<UserModel> getAll() {
118115
}
119116

120117
private void mapUserForUpdate(User sourceUser, User updateUser){
121-
if(Objects.nonNull(updateUser.getName()) && !updateUser.getName().equals("")){
122-
sourceUser.setName(updateUser.getName());
118+
if(!sourceUser.getFirstName().equals(updateUser.getFirstName())){
119+
sourceUser.setFirstName(updateUser.getFirstName());
123120
}
124-
if(Objects.nonNull(updateUser.getNationalId()) && !updateUser.getNationalId().equals("")){
125-
sourceUser.setNationalId(updateUser.getNationalId());
121+
if(!sourceUser.getLastName().equals(updateUser.getLastName())){
122+
sourceUser.setLastName(updateUser.getLastName());
123+
}
124+
if(!sourceUser.getUserName().equals(updateUser.getUserName())){
125+
sourceUser.setUserName(updateUser.getUserName());
126+
}
127+
if(!sourceUser.getNationalCode().equals(updateUser.getNationalCode())){
128+
sourceUser.setNationalCode(updateUser.getNationalCode());
129+
}
130+
if(!sourceUser.getEmail().equals(updateUser.getEmail())){
131+
sourceUser.setEmail(updateUser.getEmail());
132+
}
133+
if(!sourceUser.getMobile().equals(updateUser.getMobile())){
134+
sourceUser.setMobile(updateUser.getMobile());
135+
}
136+
if(!sourceUser.getGender().equals(updateUser.getGender())){
137+
sourceUser.setGender(updateUser.getGender());
126138
}
127139
}
128140
}

0 commit comments

Comments
 (0)