The bumpy road of two fat write parameter verification

Time:2021-5-8

background

Recently, I haven’t got together with ER Pang in the Dragon Boat Festival for a long time, so I invited Er pang to the people’s Square to kill him. Just recently, he changed his job and got a raise< br/>
IEr Pang: I heard that you’ve changed jobs recently, and you’ve still changed from a traditional software company to an Internet company. Has your salary increased a little? It’s your treat today< br/>
Er PangDon’t mention it. The salary has gone up a little, but the cost performance has become lower. I used to get off work when I arrived, but now it’s almost 12 o’clock when I get home from work< br/>
IHow about the new company? Except for working longer< br/>
Er PangWell, it’s really a little uncomfortable. It’s not that I just went in, it’s nothing,leaderI was given a simple user saving function (parameter verification). The original function that the company had done in an hour before, but I had to struggle for two or three days in this new company. It was really unbearable. I changed several versions, and finallyleaderOnly then satisfied nodded.
The bumpy road of two fat write parameter verification

Interface streaking

  • According to the way that Er Pang was written in the previous company, no matter how traditional the company is, the system serves the internal staff. It does not exist to write parameter verification in the back end, and it completely trusts the content transmitted from the front end. This does not complete the code self-test, a discovery can save data, on the asshole asshole initiation codereview(2) fat in the previous company codereviewIt doesn’t exist, as long as the function is realized. just rightleaderI have a little time today to see the code submitted by new colleagues and see how it is written. Looking at this interface of streaking,leaderThe two fat called in the past, with two fat said: “you do not write this parameter verification?”? Are you not afraid of people attacking your interface? Do not check here, use directly, not afraid to introduce SQL injection? Do not check whether the mailbox is in the format? If you don’t write this empty, you are not afraid of a large number of empty pointers. Is the service broken?… “. faceleaderThe desperate 13 ask, two fat thought probation is afraid to be a little sad Oh? You can only go back to the station with your head down and press it againleaderAnd then it was submitted again.

Parameter verification and if judgment

leaderAfter looking at it, he said: “this code is much better than last time, and the function is basically OK, but can this piece of code be written in an optimized way, which is not very elegant.”

if(Objects.isNull(user)){
            Throw new illegalargumentexception ("user cannot be empty");
        }
        if(StringUtils.isEmpty(user.getUserName())){
            Throw new illegalargumentexception ("user name cannot be empty");
        }
        if(StringUtils.isEmpty(user.getUserName())){
            Throw new illegalargumentexception ("user name cannot be empty");
        }
        if(StringUtils.isEmpty(user.getSex())){
            Throw new illegalargumentexception ("user gender cannot be empty");
        }
        if(Objects.isNull(user.getUserDetail())){
            Throw new illegalargumentexception ("user details cannot be empty");
        }
        if(Objects.isNull(user.getUserDetail().getAddress())){
            Throw new illegalargumentexception ("user address cannot be empty");
        }
        if(!"M".equals(user.getSex()) && !"F".equals(user.getSex())){
            Throw new illegalargumentexception ("illegal user gender");
        }

Two fat is also a burst of depression, or miss the previous company, ah, function is good, how to write code on how to write. Internet companies have a lot of rules. They have to write a single test after they finish writing the code, and they have to monitor a lot of broken things. They deserve this group of people. We should complain, but the code has to be changed. It’s not easy to find a job to lose during the epidemic period.
Two dogs thought that they had not learned beforeaopIs that right? With the next user-defined annotation, so that the code should be more elegant, said to do.

Implementation of custom annotation

  • First of all, a custom annotation is used to verify the parameters
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface ParameterValidator {

}
  • Configure a section to analyze theParameterValidatorAnnotation method.

Then all the requested parameters are obtained through the section. After obtaining the parameters, the annotation on the parameters is parsed. The configuration aspect is relatively simple, and the slightly more complex one is reflection parsing parameters, because it involves the nested structure of request parameters. Er Pang’s habitual programming for BaiducopyOther people’s code is never written by themselves. Baidu is basically a single-layer structure, simple basic types of objects, not related to the nested, cascade type of interest parameters. At the end of the daygithubThe world’s largest same sex dating website)I didn’t find the right one after a round. Since there is no result in using it, I can only write it by myself. Fortunately, I have learned some reflective knowledge before. It took an hour to write a rough version through recursive call. There are still many scenarios that are not considered. However, the basic conditions can be met. Some codes are as follows:

public static void checkField(Object object, Class<?> aClass) throws IllegalAccessException {
        boolean primitive = isPrimitive(aClass);
        if (primitive) {
            return;
        }
        Field[] declaredFields = filterField(aClass.getDeclaredFields());
        for (Field field : declaredFields) {
            makeAccessible(field);
            //Verify our custom annotation
            MyNotBlank fieldAnnotation = field.getAnnotation(MyNotBlank.class);
            Object currentObject = field.get(object);
            if (Objects.nonNull(fieldAnnotation)) {
                if (StringUtils.isEmpty(currentObject)) {
                    throw  new IllegalArgumentException(field.getName()+":"+fieldAnnotation.message());
                }
            }
            if (!isJavaClass(field.getType())) {
                //Recursive call, when there are cascade parameters
                checkField(currentObject);
            } else if (field.getType().isPrimitive()) {

            } else if (field.getType().isAssignableFrom(List.class)) {
                //Recursive call, parsing list type
                getList(field, currentObject);
            }
        }

    }

And then quickly test a wave, not bad, the basic function is realized, can realize the empty test, also can realize the cascade verification. The results are as follows
The bumpy road of two fat write parameter verification
However, the supported types are basic types andStringListOf
If the parameter type is array, orMapWait, we have to analyze it. At this time, my colleague Er Gou walked by and saw Er Pang knocking the code so seriously< br/>
Two dogsWhat are you writing about Er PangbugAh< br/>
Er PangMake a wheel and write a general parameter check< br/>
Two dogsIsn’t there a ready-made plan on the market now?jsr(Java Specification Requests)You can get to know about it< br/>
Er PangOK, I’ll check the information right away.

JSR (Java specification requests) Java specification proposal

  • Speaking ofjsrWe’ve got to know what it isJCP(Java Community Process)

JCP (Java community process) is an open international organization, mainly composed of Java developers and authorized persons, whose function is to develop and update.

  • What is JSR?

It is a formal request to add a standardized technical specification to JCP. Anyone can submit a JSR. (you can submit one if you feel like you’re awesome.)
To add new APIs and services to the Java platform. JSR has become an important standard in Java.

Bean Validation

Bean validation, as the name suggests, is the verification of Java beans. So far, there are three specifications for bean verification in Java.

  • JSR-303 : Bean Validation
  • JSR 349 : Bean Validation 1.1
  • JSR 380 : Bean Validation 2.0

Hibernate-Validator

Hibernate ValidatoryesBean ValidationThe reference implementation ofHibernate ValidatorProvidedJSR 303In addition to the implementation of all built-in constraints in the specification, there are some additional requirementsconstraint

code implementation

  • If the framework of the project is spring boot, hibernate validator dependency has been included in spring boot starter web(Version must be before 2.3)。2.3Later versionsspring-boot-starter-webThis dependency has been removed and needs to be introduced manuallyHibernate-validatorPlease refer to the official website for details
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
  • wrongspringbootThe project is introduced directly
<dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.17.Final</version>
</dependency>

Code demonstration:
Method in front of this note@ValidIt is necessary, otherwise it will not take effect.

    @PostMapping(value = "/save2")
    @ResponseBody
    public ResultViewModel save2(@Valid @RequestBody User user){
        boolean saveUser = saveUser(user);
        if (saveUser) {
            return ResultViewModelUtil.success();
        }
        return ResultViewModelUtil.error();
    }

Just mark the rule annotation that needs verification on the entity class.

//The value of the annotated element must be a string and cannot be null. After calling trim(), the length must be greater than 0
@NotBlank(message = "")

//The value of the annotated element cannot be null, but it can be "null", which is used for non null verification of basic data types. Moreover, the annotated fields can use @ size, @ max, @ min to control the size of field values
@NotNull(message = "")

//The annotated element, whose value cannot be null and whose length must be greater than 0, is generally used in collection classes
@NotEmpty(message = "")

//The annotated element must conform to the specified regular expression.
@Pattern(regexp = "", message = "")

//The size of the annotated element must be within the specified range.
@Size(min =, max =)

//For the annotated element, the value must be a number, and the value must be greater than or equal to the specified minimum value
@Min (value = value within long, message =)

//Annotated element, the value must be a number, and the value must be less than or equal to the specified maximum value
@Max (value = value within long, message =)

//The value of the annotated element must be a number, and its value must be greater than or equal to the specified minimum value
@Decimalmin (value = can be decimal, message =)

//The value of the annotated element must be a number, and its value must be less than or equal to the specified maximum value
@Decimalmax (value = can be decimal, message =)

//Annotated element, value must be null
@Null(message = "")

//The annotated element must be a number with an acceptable value
@Digits(integer =, fraction =)

//Annotated element, value must be true
@AssertTrue(message = "")

//The value of the annotated element must be false
@AssertFalse(message = "")

//The annotated element must be a past date
@Past(message = "")

//The annotated element must be a future date
@Future(message = "")

//The annotated element must be an email address
@Email(regexp = "", message = "")
//The annotated element must be in the appropriate range
@Range(min =, max =, message = "")

//The size of the commented string must be within the specified range
@Length(min =, max =, message = "")

The only thing you need to pay attention to is that if it’s cascading verification, it needs to be added to the outermost layer@Valid
Why is it necessary to mark on the last time of verification@ValidIn this annotation, the validation will take effect? If you know or are interested, you can go to see the source code and leave me a message.
The bumpy road of two fat write parameter verification
And then in the configuration of a global exception catcher is good, because of the length of the code will not be posted, the code uploaded to thegithubIt’s on.
Calibration results:
The bumpy road of two fat write parameter verification

summary

  • Hibernate-ValidatorYou can also customize the annotation implementation.
  • You can also group check (there is a scenario where you don’t need to verify when adding user informationuserId(because of system generation); You need to verify when you modify ituserIdIn this case, users can go tovalidatorGroup verification function of
  • If the project is notspringbootFor example, using jfinal framework (this is a domestic framework, most people can not know), orsoaWhen calling parameter verification, how can I use columns?
  • More use posture you are interested in can go to the official website to unlock Oh, but the above introduction of daily development can basically meet the needs.
  • Two fat see this richapi, as well as the simple usage of fried chicken, I quickly deleted the wheel I wrote and immediately replaced it with this oneHibernate-ValidatorFramework. After revision and submission,leaderFinally, a satisfied smile appeared on his face.
  • Project address

end

  • Due to my lack of talent and learning, it is inevitable that there will be mistakes. If you find any mistakes, please leave me a message to point them out, and I will correct them.
  • If you think the article is not bad, your forwarding, sharing, appreciation, likes and comments are my greatest encouragement.
  • Thank you for your reading. Welcome and thank you for your attention.

The bumpy road of two fat write parameter verification

reference resources
http://docs.jboss.org/hiberna…(Chinese version of the official website
https://docs.jboss.org/hibern…
https://juejin.im/post/5dd8d4…
https://www.cnblogs.com/mr-ya…

Recommended Today

Get system performance data with go language gopsutil Library

psutilIs a cross platform process and system monitoring Python library, andgopsutilIt is the implementation of go language version. This paper introduces its basic use. Go language has the characteristics of simple deployment and good performance, which is very suitable for doing some services such as collecting system information and monitoring. The gopsutil library introduced in […]