Solve the problem that the null value passed by the separated item changes to “null” string

Time:2020-6-2

preface

Solve the problem that the project separated from the front end and the back end passes in null value and becomes “null” string in the background.

Let’s start with the conclusion: This is not a problem at all, but a fact. When JSON passes values, null becomes a “null” string.

The solution is to add interceptors in the foreground to filter out the null parameters.

problem

For an angular + spring MVC project, if the value transferred from the current platform to the background is null, it will become “null” in the background.

The front desk initiates the request as follows:

  constructor(private httpClient: HttpClient) { }
  page(params: {clientId?: number, page: number, size: number, message?: string, level?: string}): Observable<Page<Log>> {
    const Params = {
      clientId: params.clientId ? params.clientId.toLocaleString() : null,
      page: params.page.toLocaleString(),
      size: params.size.toLocaleString(),
      message: params.message ? params.message : null,
      level: params.level ? params.level : null
    };
    const url = '/log/page';
    console.log(Params);
    return this.httpClient.get<Page<Log>>(url, {params: Params});
  }

In the foreground, the value of all parameters will be determined. If it is null or undefined, the parameter will be null.

In the browser console, the requested parameter is output, which is real null:
Solve the problem that the null value passed by the separated item changes to

The method requested in the background is as follows:

    @GetMapping("page")
    @JsonView(page.class)
    public Page<Log> page(@RequestParam(required = false) Long clientId,
                          @RequestParam(required = false) String message,
                          @RequestParam(required = false) String level,
                          Pageable pageable) {
        logger.info(message+""+level);
        return new PageImpl(logService.page(clientId, level, message, pageable));
    }

But when judging the null value in the background, it is found unexpectedly,All null judgments are not valid, even if the incoming is null, the background will not process it as null, so an error is reported.

I broke in backstage and found outAfter all nulls are sent to the background, they become “null”
Solve the problem that the null value passed by the separated item changes to

Null becomes string, which is why null judgment fails.

reason

Before we solve the problem, we need to understand that JSON is used to transfer values from the foreground to the background.

JSONJavaScriptObjectNAnnotation, JavaScript object representation.

Although there is JS in the name, JSON is not exclusive to JavaScript, but a language independentText format(like markdown, XML, etc.) so many languages can parse JSON, which has become a tool for passing values between different languages.

When the actual value is passed, the foreground will change the parameter into a JSON string.

Any JSON string, as follows:

[ { 
"id": 1, 
"level": "DEBUG", 
"levelCode": 1, 
"logger": "123", 
"context": "1", 
"thread": "", 
"message": "123", 
"timestamp": "2020-03-15T21:53:32.000+0000", 
},
{ "id": 2, 
"level": "INFO", 
"levelCode": 2, 
"logger": "123", 
"context": "2", 
"thread": "", 
"message": "123", 
"timestamp": "2020-03-10T21:53:32.000+0000"
} ]

As you can see, JSON uses the form of key value pairs, and it is worth noting that all information is strings or numbers.
In other words, there are only strings and numbers in JSON.

Because the data cannot be directly transferred to the object during data transmission, it is necessary to convert it to JSON string when the value is actually transferred, regardless of the typecharacter stringornumber

When the background receives the parameter, the background does not know what type it is. It can only try to cast the string according to the specified parameter type.

Solve the problem that the null value passed by the separated item changes to

Therefore, if there is null, the foreground can only be converted to “null”, which results in the background can only receive “null”, evenIndistinguishableNull and ‘null’.

The more serious problem is that if the parameter received in the background is a number type (long, int, double) and the incoming in the foreground is null, the background 500 will be directly caused due to the string cast to number failure

solve

The overall idea is to add an HTTP request interceptor in the foreground. If there is null in the parameter, remove the parameter.
Since there is no such parameter at all when the request is initiated, what the background receives is real null.

For beginners, it may be difficult to set up interceptors in angular. Please refer to: interceptors — a tutorial for getting started with springboot + angular

Just add it to the blocker that has been written to intercept HTTP requests, and change it slightly:

/**
     *Filter to null and undefined
     */
    let cleanedParams = new HttpParams();
    //Request needs to be replaced with its own
    request.params.keys().forEach(x => {
      if (isDefined(request.params.get(x))) {
        cleanedParams = cleanedParams.append(x, req.params.get(x));
      }
    });
    request = request.clone({headers, params: cleanedParams});

After the current interceptor takes effect, you can see from the console that there are only two parameters left: page and size. Other parameters with null values are filtered out:

Solve the problem that the null value passed by the separated item changes to

The background does become null:

Solve the problem that the null value passed by the separated item changes to

At this point, null parameters are successfully filtered out.

summary

It’s not a problem at all that null becomes “null” when the value is passed from front to back, but because of the principle of JSON, it can only become a string.

The solution is to filter the null parameter in the foreground interceptor. After filtering, this parameter will not be passed. What the background receives is real null.

By solving the problem this time, I have learned more about interceptors and JSON.