Scenario reduction

Simple business scenario simulation:

Let’s say you’re working on a grade entry system, and you happily write a background interface using the Spring Boot framework to receive Student objects from the foreground browser and insert them into the background database.

We define the passed Student object as:

public class Student { private String name; Private Integer score; Private String mobile; // Phone number (11 digits)}Copy the code

Write a Post request to the backend interface to receive the Student object from the webpage:

@RestController public class TestController { @Autowired private StudentService studentService; @PostMapping("/add") public String addStudent( @RequestBody Student student ) { studentService.addStudent( student ); Return "SUCCESS"; }}Copy the code

At this point, I’m sure you can see the vulnerability in the above code, because we don’t do any validation on the passed Student object, such as:

Student = null; Student = null; Student score = 101 Student’s mobile phone number is 11 digits. What if I filled in an extra digit? . , etc.

Although these data are generally verified in the front page, we, as a rigorous and conscientious back-end development engineer, must make strict verification of each incoming data, so how should we write?

@PostMapping("/add") public String addStudent( @RequestBody Student student ) { if( student == null ) return "Student object passed as null, please pass "; If (student. GetName () = = null | | "" equals (student. The getName ())) return" the incoming student's name is empty, please call value "; If (student.getscore ()==null) return "; If ((student getScore () < 0) | | (student) getScore () > 100)) return "the incoming student achievement is flawed, score should be between 0 ~ 100". If (student. GetMobile () = = null | | "" equals (student) getMobile ())) return" of the incoming students telephone number is empty, please call value "; if( student.getMobile().length()! =11) return "The length of the incoming student's phone number is incorrect, it should be 11 digits "; studentService.addStudent( student ); Return "SUCCESS"; }Copy the code

Student = Student; Student = Student; Student = Student; Student = Student; Student = Student; I can’t imagine!


Blessed be god’s word!

The Spring framework has made it easy for us to use annotations to verify interactive data. In this example, we just need to add annotations to the fields of the Student entity class.

Public class Student {@notnull (message = "null, please pass ") @notempty (message =" null, please pass ") private String name; @min (value = 0,message = "error ") @notnull (value = 0,message =" error ") ") @max (value = 100,message = ") private Integer score; // fraction @notnull (message = "incoming phone is null, please pass the value ") @notempty (message =" incoming phone is empty string, Please pass the value ") @length (min = 11, Max = 11, message = "The Length of the incoming phone number is incorrect, it must be 11 digits ") private String mobile; // Phone number}Copy the code

Of course, we also need to validate the incoming Student with the @valid annotation at the entry of the object:

@postMapping ("/add") public String addStudent(@requestBody @valid Student Student) { All kinds of complicated parameter verification work are saved! One line of code. Don't write studentService addStudent (student); Return "SUCCESS"; }Copy the code

At this point, if a field is passed in incorrectly, for example, I misread the student’s score as 101 when transmitting data, the interface will return the result with the error details:

Of course, the principle of this matter, since the use of annotations, nothing more than the Java is a variety of reflection and other knowledge to achieve, interested partners can take this opportunity to study!


Unified data exception interception

The above use of annotations to do unified data verification feel very beautiful, but the only defect is that the returned results are too complicated, not necessarily the format we need, we need to do unified processing, for example: I just want to check the specific parameters of the error message to cut out and return to the front end.

To do this, we configure a global uniform exception interceptor for the project to format the return results of all data validations.

@ControllerAdvice @ResponseBody public class GlobalExceptionInterceptor { @ExceptionHandler(value = Exception.class) public String exceptionHandler(HttpServletRequest request, Exception e) { String failMsg = null; If (e instanceof MethodArgumentNotValidException) {/ / to get the parameters calibration specific exception information prompt failMsg = ((MethodArgumentNotValidException) e).getBindingResult().getFieldError().getDefaultMessage(); } return failMsg; // spit directly back to the front end}}Copy the code

As shown in the above code, we unified global intercept the abnormal MethodArgumentNotValidException parameters calibration, and just to get the corresponding abnormal detailed Message information to spit to the front, at this time back to the front end of the data is much more clear:

Yes, very elegant!

Make a little progress every day! Peace!