В веб-приложениях данные типа Long во внутреннем Java-коде часто сталкиваются с проблемой потери точности при передаче во внешний интерфейс. Это происходит главным образом потому, что тип Number в JavaScript не может точно представлять целочисленные значения за пределами безопасного целочисленного диапазона (т. е. от -9007199254740991 (-2^53 + 1) до 9007199254740991 (2^53 - 1)). Поэтому, когда данные типа Long внутренней части Java превышают этот диапазон, внешний JavaScript потеряет точность при анализе данных.
Эта проблема возникает в основном в числовых полях. Если серверная часть определена с использованием типа Long или поле получено с использованием типа Long, прогресс будет потерян.
В бэкэнде Java,Можно использоватьJacksonбиблиотека@JsonFormat
Аннотируйте будущееLongТиповое поле, сериализованное в строковый тип。так,Когда данные передаются во внешний интерфейс,будет передано как строка,Это позволяет избежать проблемы потери точности.,Если поле кода возвращается, оно преобразуется в строку.
import com.fasterxml.jackson.annotation.JsonFormat;
public class MyEntity {
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long myLongField;
}
Другой метод — просмотреть каждое поле типа Long, преобразовать его значение в строковый тип, а затем передать данные после запроса данных из базы данных. Этот метод более громоздкий, но позволяет эффективно решить проблему потери точности.
Чтобы решить эту проблему более удобно, вы также можете выполнить глобальную обработку во всем веб-приложении и преобразовать все данные типа Long в строковый тип. Этого можно добиться, настроив ObjectMapper Джексона. Это также относительно распространенный метод, и при общей разработке используется глобальная конфигурация.
Во-первых, вам нужно ввести в проект зависимости Джексона:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
</dependency>
Затем,Вам необходимо настроить класс реализации WebMvcConfigurer.,переписать вconfigureMessageConverters
метод,Добавьте пользовательский HttpMessageConverter для обработки данных типа Long. Код выглядит следующим образом:
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// Настройте StringHttpMessageConverter (при необходимости)
converters.add(new StringHttpMessageConverter());
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
ObjectMapper objectMapper = builder.build();
SimpleModule simpleModule = new SimpleModule();
// Зарегистрируйте ToStringSerializer для типа Long, чтобы сериализовать его в строку.
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
// Добавьте настроенный ObjectMapper в MappingJackson2HttpMessageConverter.
converters.add(new MappingJackson2HttpMessageConverter(objectMapper));
// Если вы наследуете другие классы реализации WebMvcConfigurer, вы можете вызвать super.configureMessageConverters(converters);
// Но в этом примере мы не наследуем другие классы реализации, поэтому нет необходимости вызывать
}
}
Благодаря приведенной выше конфигурации данные типа Long можно преобразовать в строковый тип во всем веб-приложении, что позволяет избежать проблемы потери точности при обработке во внешнем JavaScript. Этот метод прост, эффективен и не требует значительных изменений исходного кода. Это очень практичное решение.