暂存提交
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
package com.baiyue.common.web;
|
||||
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* 统一将 Java 长整型序列化为 JSON 字符串,避免浏览器对雪花 ID 产生精度截断。
|
||||
*
|
||||
* <p>请求反序列化仍兼容 JSON 字符串和安全范围内的 JSON 数字;数据库与领域模型继续使用
|
||||
* {@code BIGINT}/{@code Long},本配置只改变 HTTP JSON 表达。</p>
|
||||
*/
|
||||
@AutoConfiguration
|
||||
public class LongIdJacksonConfiguration {
|
||||
|
||||
@Bean
|
||||
Jackson2ObjectMapperBuilderCustomizer longAsStringJacksonCustomizer() {
|
||||
return builder -> builder
|
||||
.serializerByType(Long.class, ToStringSerializer.instance)
|
||||
.serializerByType(Long.TYPE, ToStringSerializer.instance);
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
com.baiyue.common.web.LongIdJacksonConfiguration
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.baiyue.common.web;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.mock.web.MockFilterChain;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
@@ -7,6 +8,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DisplayName("请求链路标识过滤功能")
|
||||
class CorrelationIdFilterTest {
|
||||
private final CorrelationIdFilter filter = new CorrelationIdFilter();
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.baiyue.common.web;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.core.MethodParameter;
|
||||
@@ -11,6 +12,7 @@ import java.lang.reflect.Method;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DisplayName("全局异常响应")
|
||||
class GlobalExceptionHandlerTest {
|
||||
private final GlobalExceptionHandler handler = new GlobalExceptionHandler();
|
||||
|
||||
@@ -26,7 +28,7 @@ class GlobalExceptionHandlerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void 查询参数类型错误映射为四百而不是五百() throws Exception {
|
||||
void invalidQueryParameterTypeMapsToBadRequest() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
Method method = GlobalExceptionHandlerTest.class.getDeclaredMethod("paging", long.class);
|
||||
MethodParameter parameter = new MethodParameter(method, 0);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.baiyue.common.web;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DisplayName("长整型标识序列化")
|
||||
class LongIdJacksonConfigurationTest {
|
||||
|
||||
private final ObjectMapper objectMapper = configuredObjectMapper();
|
||||
|
||||
@Test
|
||||
void longAndPrimitiveLongShouldBeSerializedAsStrings() throws Exception {
|
||||
String json = objectMapper.writeValueAsString(
|
||||
new IdPayload(190000000000000001L, 190000000000000002L));
|
||||
|
||||
assertThat(json).isEqualTo(
|
||||
"{\"boxedId\":\"190000000000000001\",\"primitiveId\":\"190000000000000002\"}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringLongShouldStillBeDeserialized() throws Exception {
|
||||
IdPayload payload = objectMapper.readValue(
|
||||
"{\"boxedId\":\"190000000000000001\",\"primitiveId\":\"190000000000000002\"}",
|
||||
IdPayload.class);
|
||||
|
||||
assertThat(payload.boxedId()).isEqualTo(190000000000000001L);
|
||||
assertThat(payload.primitiveId()).isEqualTo(190000000000000002L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfigurationShouldApplyToSpringObjectMapper() {
|
||||
new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(
|
||||
JacksonAutoConfiguration.class, LongIdJacksonConfiguration.class))
|
||||
.run(context -> {
|
||||
ObjectMapper springObjectMapper = context.getBean(ObjectMapper.class);
|
||||
assertThat(springObjectMapper.writeValueAsString(new IdPayload(1L, 2L)))
|
||||
.isEqualTo("{\"boxedId\":\"1\",\"primitiveId\":\"2\"}");
|
||||
});
|
||||
}
|
||||
|
||||
private ObjectMapper configuredObjectMapper() {
|
||||
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
|
||||
new LongIdJacksonConfiguration().longAsStringJacksonCustomizer().customize(builder);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private record IdPayload(Long boxedId, long primitiveId) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user