SoFunction
Updated on 2025-03-10

Solve the problem of loss of precision in the back-end to front-end in Long type

Long type backend to front-end accuracy loss problem

In development, the backend often needs to deal with some large valuesLongType data (id, etc.). However, when this data is passed to the front end through the interface, there may be a problem of accuracy loss.

reason:

JavaScriptNumberType complianceIEEE 754 Double precision floating point number standard, can only accurately represent the range within-(2^53 - 1)arrive2^53 - 1The integer between (approximately equal to-9007199254740991arrive9007199254740991)。

This means that any integer beyond this range cannot be accurately represented in JavaScript.

For example:

(9007199254740991);    // Output: 9007199254740991 (accurate)(9007199254740992);    // Output: 9007199254740992 (accurate)(9007199254740993);    // Output:9007199254740992(Loss of accuracy)

In the backend (e.g. Java),LongThe range of types is-2^63arrive2^63 - 1,Right now-9223372036854775808arrive9223372036854775807

This value can be accurately represented in Java, but when passed to the front-end JavaScript environment through JSON, it often occurs due to JavaScript numerical accuracy limitations.Loss of accuracyThe problem.

Typical scenarios

When the backend returns an ID value1234567890123456789, the front end may receive it1234567890123456000, which leads to data errors.

Solution

Solution 1: The backend serializes the Long type to the String type

A simple and effective solution is to put the backendLongType values ​​are serialized toString, so that the front-end will process it as a string, thus avoiding the problem of loss of precision. The following is a specific implementation method.

1. Use @JsonSerialize annotation to process fields separately

If you just need to process a specific field (e.g.id), can be added on the field@JsonSerializeAnnotation, specify Jackson to useToStringSerializerSerializer.

import ;
import ;

public class PassengerQueryResp {

    @JsonSerialize(using = )
    private Long id;

    private Long memberId;
    private String name;
    private String idCard;

    // Getter and Setter}

Configure thisObjectMapperAfter that, allLongType fields are converted to string format when serialized, and no longer need to add annotations on a field-by-field basis.

2. Configure global ObjectMapper settings

If needed for allLongFields of type are processed in strings, and a global can be defined in the Spring Boot configuration class.ObjectMapperBean, useSimpleModuleregisterToStringSerializer, this will do allLongThe type field takes effect.

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = (false).build();
        SimpleModule simpleModule = new SimpleModule();
        (, );
        (simpleModule);
        return objectMapper;
    }
}

Detailed explanation of the function of configuration classes

existJacksonConfigIn the class, the following code willLongType serialization toString

SimpleModule simpleModule = new SimpleModule();
(, );
(simpleModule);

Specific working principle

Boot automatic configurationObjectMapper

  • Spring Boot comes with Jackson as the default JSON processing library and is automatically configured in the background.ObjectMapper
  • When you introduce Jackson into your project, Spring Boot will automatically load a globally sharedObjectMapperInstance, used for all JSON serialization and deserialization operations.

2. Automatic JSON conversion of controller

  • In Spring MVC, the controller (@RestControlleror@Controller) The return value of the method in ) will be automatically converted to JSON format, which is converted by Spring BootObjectMapperdeal with.
  • For example:
@RestController
public class UserController {
    @GetMapping("/user")
    public User getUser() {
        return new User(123456789012345L, "Alice");
    }
}
  • whenUserSpring MVC will be automatically used when the object is returnedObjectMapperSerialize it as a JSON response and send it to the client.
  • If you configured itJacksonConfigClass, Spring will use your configurationObjectMapper, so allLongThe type field will be automatically output as a string to avoid loss of precision.

3. CustomizeObjectMapper Global effects of configuration

By customizingJacksonConfig, actually let Spring Boot use what you definedObjectMapperBeans are configured as global.

Spring Boot will automatically detect the applicationObjectMapperBean and use it for all JSON serialization and deserialization operations, which include:

  • @RestControllerThe returned object.
  • @RequestBodyand@ResponseBodyJSON requests and responses processed by annotation.
  • Other places where JSON is required for Spring Boot internal or third-party libraries.

Summarize

Handling in backend developmentLongWhen typed data, it is very important to pay attention to the accuracy limitations of JavaScript.

By configuring Jackson'sObjectMapper, can make allLongType fields are serialized to strings, thus avoiding the problem of loss of precision.

Spring Boot's automated configuration features allow us to avoid manual callsObjectMapper, this configuration can be applied globally, so that the data transmitted by the backend to the frontend can be accurate when the value is large.

The above is personal experience. I hope you can give you a reference and I hope you can support me more.