暂存提交

This commit is contained in:
2026-07-31 16:53:07 +08:00
parent 45358ef40f
commit 704cb15ccf
98 changed files with 1944 additions and 134 deletions
@@ -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);
}
}
@@ -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) {
}
}