Long type backend to front-end accuracy loss problem
In development, the backend often needs to deal with some large valuesLong
Type 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:
JavaScriptNumber
Type complianceIEEE 754 Double precision floating point number standard, can only accurately represent the range within-(2^53 - 1)
arrive2^53 - 1
The integer between (approximately equal to-9007199254740991
arrive9007199254740991
)。
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),Long
The range of types is-2^63
arrive2^63 - 1
,Right now-9223372036854775808
arrive9223372036854775807
。
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 backendLong
Type 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@JsonSerialize
Annotation, specify Jackson to useToStringSerializer
Serializer.
import ; import ; public class PassengerQueryResp { @JsonSerialize(using = ) private Long id; private Long memberId; private String name; private String idCard; // Getter and Setter}
Configure thisObjectMapper
After that, allLong
Type 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 allLong
Fields of type are processed in strings, and a global can be defined in the Spring Boot configuration class.ObjectMapper
Bean, useSimpleModule
registerToStringSerializer
, this will do allLong
The 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
existJacksonConfig
In the class, the following code willLong
Type 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 shared
ObjectMapper
Instance, used for all JSON serialization and deserialization operations.
2. Automatic JSON conversion of controller
- In Spring MVC, the controller (
@RestController
or@Controller
) The return value of the method in ) will be automatically converted to JSON format, which is converted by Spring BootObjectMapper
deal with. - For example:
@RestController public class UserController { @GetMapping("/user") public User getUser() { return new User(123456789012345L, "Alice"); } }
- when
User
Spring MVC will be automatically used when the object is returnedObjectMapper
Serialize it as a JSON response and send it to the client. - If you configured it
JacksonConfig
Class, Spring will use your configurationObjectMapper
, so allLong
The 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 definedObjectMapper
Beans are configured as global.
Spring Boot will automatically detect the applicationObjectMapper
Bean and use it for all JSON serialization and deserialization operations, which include:
-
@RestController
The returned object. -
@RequestBody
and@ResponseBody
JSON requests and responses processed by annotation. - Other places where JSON is required for Spring Boot internal or third-party libraries.
Summarize
Handling in backend developmentLong
When typed data, it is very important to pay attention to the accuracy limitations of JavaScript.
By configuring Jackson'sObjectMapper
, can make allLong
Type 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.