反序列化 属性 'created' 时出现问题(预期类型:[简单类型,class java.time.LocalDate]
Problem deserializing property 'created' (expected type: [simple type, class java.time.LocalDate]
我使用集成 class,其中测试失败。下面提供了class,
public class EllaServiceIntegrationTest {
private static final String ELLA_JSON_RESPONSE_FRAUD = "{\n" + " \"score\": 707,\n" + " \"reason\": \"DOMAIN_DOES_NOT_EXIST\",\n"
+ " \"riskBand\": 4,\n" + " \"email\": {\n"
+ " \"emailAddress\": \"fraudster@fraud.com\",\n"
+ " \"exists\": 4,\n"
+ " \"firstVerificationDate\": \"2019-05-31T19:08:20.7713155Z\",\n"
+ " \"firstVerificationDays\": 0,\n" + " \"totalHits\": 31,\n"
+ " \"uniqueHits\": 1,\n" + " \"score\": {\n"
+ " \"reason\": \"DOMAIN_DOES_NOT_EXIST\",\n"
+ " \"riskLevel\": 6,\n" + " \"relevantInfoId\": 10900\n"
+ " }\n" + " },\n" + " \"domain\": {},\n" + " \"phone\": {},\n"
+ " \"shipAddress\": {\n" + " \"addressCheck\": 4,\n"
+ " \"score\": {\n"
+ " \"reason\": \"SHIPADDRESS_NOT_COMPLETE\",\n"
+ " \"riskLevel\": 6,\n" + " \"relevantInfoId\": 40950\n"
+ " }\n" + " },\n" + " \"billingAddress\": {\n"
+ " \"addressCheck\": 4,\n" + " \"score\": {\n"
+ " \"reason\": \"BILLADDRESS_NOT_COMPLETE\",\n"
+ " \"riskLevel\": 6,\n" + " \"relevantInfoId\": 50950\n"
+ " }\n" + " },\n" + " \"transaction\": {\n"
+ " \"isPrepaid\": false,\n" + " \"cardType\": 6,\n"
+ " \"score\": {\n"
+ " \"reason\": \"MODERATE_RISK_TRANSACTION\",\n"
+ " \"riskLevel\": 3,\n" + " \"relevantInfoId\": 69999\n"
+ " }\n" + " },\n" + " \"device\": {},\n" + " \"ip\": {},\n"
+ " \"service\": {\n" + " \"existingCustomer\": false,\n"
+ " \"score\": {\n"
+ " \"reason\": \"MODERATE_RISK_SERVICE_DETAILS\",\n"
+ " \"riskLevel\": 3,\n" + " \"relevantInfoId\": 79999\n"
+ " }\n" + " },\n"
+ " \"correlationId\": \"efc8a177-94d2-4a01-bd4f-af3b0e33be26\",\n"
+ " \"version\": \"1.0\",\n"
+ " \"created\": \"2019-05-31T19:08:20.7712944Z\",\n"
+ " \"status\": \"SUCCESSFUL\"\n" + "}";
private static final String ELLA_JSON_RESPONSE_NON_FRAUD =
"{\"status\":\"SUCCESSFUL\",\"result\":{\"cutoff\":0.5,\"classification\":\"non_fraud\",\"non_fraud_proba\":0.5176171064376831,"
+ "\"fraud_proba\":0.4823829233646393}}";
private final static String ELLA_ENDPOINT = "/ella-web/api/v1/score";
private EllaService ellaService;
@Rule
public WireMockRule wireMockRule = new WireMockRule( wireMockConfig().dynamicPort() );
@Before
@SuppressWarnings( "resource" )
public void setup() {
int port = wireMockRule.port();
System.setProperty( "ella.uri", "http://localhost:" + port + ELLA_ENDPOINT );
System.setProperty( "ella.internal.customer.filter", String.valueOf( false ) );
System.setProperty( "ella.external.customer.filter", String.valueOf( false ) );
System.setProperty( "ella.shop.id.filter", "123456,56789,545334" );
ApplicationContext context = new AnnotationConfigApplicationContext( EllaConfiguration.class );
ellaService = context.getBean( EllaService.class );
}
@Test
public void testInvokeEllaCallsEllaWithRatepayHeadersAsyncCall() {
wireMockRule.stubFor( post( urlEqualTo( ELLA_ENDPOINT ) ).withHeader( ACCEPT, equalTo( APPLICATION_JSON_UTF8_VALUE ) )
.willReturn( okJson( ELLA_JSON_RESPONSE_FRAUD ) ) );
IrisBo irisBo = EllaTestDataProvider.createValidIrisBoWithRequest();
ellaService.invokeEllaAsync( irisBo );
verify( postRequestedFor( urlEqualTo( ELLA_ENDPOINT ) )
.withHeader( RatepayHeaders.HEADER_GATEWAY_REQUEST_ID, equalTo( EllaTestConstants.VALID_GATEWAY_ID ) )
.withHeader( RatepayHeaders.HEADER_TRANSACTION_ID, equalTo( EllaTestConstants.VALID_TRX_ID ) ) );
}
}
我得到下面提供的错误堆栈,
com.ratepay.iris.ella.dto.response.EllaGatewayUnsuccessfulResponseException: Problem deserializing property 'created' (expected type: [simple type, class java.time.LocalDate]; actual type: `java.time.OffsetDateTime`), problem: argument type mismatch
at [Source: (String)"{
"score": 707,
"reason": "DOMAIN_DOES_NOT_EXIST",
"riskBand": 4,
"email": {
"emailAddress": "fraudster@fraud.com",
"exists": 4,
"firstVerificationDate": "2019-05-31T19:08:20.7713155Z",
"firstVerificationDays": 0,
"totalHits": 31,
"uniqueHits": 1,
"score": {
"reason": "DOMAIN_DOES_NOT_EXIST",
"riskLevel": 6,
"relevantInfoId": 10900
}
},
"domain": {},
"phone": {},
"s"[truncated 1013 chars]; line: 57, column: 16] (through reference chain: com.ratepay.iris.ella.dto.response.EllaResponseDto["created"])
at com.ratepay.iris.ella.service.EllaService.invokeEllaAsync(EllaService.java:95)
at
com.ratepay.iris.ella.service.EllaServiceIntegrationTest.testInvokeEllaCallsEllaWithRatepayHeadersAsyncCall(EllaServiceIntegrationTest.java:108)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at com.github.tomakehurst.wiremock.junit.WireMockRule.evaluate(WireMockRule.java:73)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:139)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
at com.ratepay.commons.web.util.io.http.connector.RequestExecutor.createResponseWithBody(RequestExecutor.java:309)
at com.ratepay.commons.web.util.io.http.connector.RequestExecutor.createSucessfulResponse(RequestExecutor.java:298)
at com.ratepay.commons.web.util.io.http.connector.RequestExecutor.createResponse(RequestExecutor.java:284)
at com.ratepay.commons.web.util.io.http.connector.RequestExecutor.submit(RequestExecutor.java:123)
at com.ratepay.commons.web.util.io.http.connector.RequestExecutor.submitRequest(RequestExecutor.java:89)
at com.ratepay.commons.web.util.io.http.connector.ServiceConnector.doCall(ServiceConnector.java:210)
at com.ratepay.commons.web.util.io.http.connector.ServiceConnector.call(ServiceConnector.java:125)
at com.ratepay.iris.ella.service.EllaService.callEllaService(EllaService.java:128)
at com.ratepay.iris.ella.service.EllaService.invokeEllaAsync(EllaService.java:92)
它显然是由 ELLA_JSON_RESPONSE_FRAUD
中定义的返回响应的 + " \"created\": \"2019-05-31T19:08:20.7712944Z\",\n"
行构成的。
我提供了一个响应 DTO 示例来显示时间值定义,
@JsonInclude( JsonInclude.Include.NON_NULL )
@Getter
@Setter
public class EllaResponseDto extends BaseDto {
private String trackingId;
private Integer score;
private String reason;
private Integer riskBand;
private EmailDto email;
private DomainDto domain;
private PhoneDto phone;
private AddressDto shipAddress;
private AddressDto billingAddress;
private TransactionDto transaction;
private DeviceDto device;
private IpDto ip;
private ServiceDto service;
private String correlationId;
private String version;
@JsonDeserialize( using = JavaOffsetDateTimeDeserializer.class )
@JsonSerialize( using = JavaOffsetDateTimeSerializer.class )
private LocalDate created;
private EllaStatus status;
}
如果我正确理解问题,它在错误堆栈中表示为 Problem deserializing property 'created' (expected type: [simple type, class java.time.LocalDate]; actual type:
java.time.OffsetDateTime), problem: argument type mismatch
。
为了解决这种情况,我将创建日期定义为 private LocalDate created
,带有注释的序列化和反序列化选项。显然,这是行不通的。
我该如何解决这个问题?
@JsonDeserialize( using = JavaOffsetDateTimeDeserializer.class )
@JsonSerialize( using = JavaOffsetDateTimeSerializer.class )
private LocalDate created;
Deserializer 将字符串转换为 Offsetdatetime 但创建的数据类型是 LocalDate,我认为从测试数据“2019-05-31T19:08:20.7712944Z”(包括区域)来看,您应该使用 OffsetDateTime 而不是 LocalDate
我找到了解决问题的方法。我需要从
更改所有 DTO 类 的注释
@JsonDeserialize( using = JavaOffsetDateTimeDeserializer.class )
@JsonSerialize( using = JavaOffsetDateTimeSerializer.class )
至
@JsonSerialize( using = LocalDateSerializer.class )
@JsonDeserialize( using = LocalDateDeserializer.class )
现在测试通过了。
我使用集成 class,其中测试失败。下面提供了class,
public class EllaServiceIntegrationTest {
private static final String ELLA_JSON_RESPONSE_FRAUD = "{\n" + " \"score\": 707,\n" + " \"reason\": \"DOMAIN_DOES_NOT_EXIST\",\n"
+ " \"riskBand\": 4,\n" + " \"email\": {\n"
+ " \"emailAddress\": \"fraudster@fraud.com\",\n"
+ " \"exists\": 4,\n"
+ " \"firstVerificationDate\": \"2019-05-31T19:08:20.7713155Z\",\n"
+ " \"firstVerificationDays\": 0,\n" + " \"totalHits\": 31,\n"
+ " \"uniqueHits\": 1,\n" + " \"score\": {\n"
+ " \"reason\": \"DOMAIN_DOES_NOT_EXIST\",\n"
+ " \"riskLevel\": 6,\n" + " \"relevantInfoId\": 10900\n"
+ " }\n" + " },\n" + " \"domain\": {},\n" + " \"phone\": {},\n"
+ " \"shipAddress\": {\n" + " \"addressCheck\": 4,\n"
+ " \"score\": {\n"
+ " \"reason\": \"SHIPADDRESS_NOT_COMPLETE\",\n"
+ " \"riskLevel\": 6,\n" + " \"relevantInfoId\": 40950\n"
+ " }\n" + " },\n" + " \"billingAddress\": {\n"
+ " \"addressCheck\": 4,\n" + " \"score\": {\n"
+ " \"reason\": \"BILLADDRESS_NOT_COMPLETE\",\n"
+ " \"riskLevel\": 6,\n" + " \"relevantInfoId\": 50950\n"
+ " }\n" + " },\n" + " \"transaction\": {\n"
+ " \"isPrepaid\": false,\n" + " \"cardType\": 6,\n"
+ " \"score\": {\n"
+ " \"reason\": \"MODERATE_RISK_TRANSACTION\",\n"
+ " \"riskLevel\": 3,\n" + " \"relevantInfoId\": 69999\n"
+ " }\n" + " },\n" + " \"device\": {},\n" + " \"ip\": {},\n"
+ " \"service\": {\n" + " \"existingCustomer\": false,\n"
+ " \"score\": {\n"
+ " \"reason\": \"MODERATE_RISK_SERVICE_DETAILS\",\n"
+ " \"riskLevel\": 3,\n" + " \"relevantInfoId\": 79999\n"
+ " }\n" + " },\n"
+ " \"correlationId\": \"efc8a177-94d2-4a01-bd4f-af3b0e33be26\",\n"
+ " \"version\": \"1.0\",\n"
+ " \"created\": \"2019-05-31T19:08:20.7712944Z\",\n"
+ " \"status\": \"SUCCESSFUL\"\n" + "}";
private static final String ELLA_JSON_RESPONSE_NON_FRAUD =
"{\"status\":\"SUCCESSFUL\",\"result\":{\"cutoff\":0.5,\"classification\":\"non_fraud\",\"non_fraud_proba\":0.5176171064376831,"
+ "\"fraud_proba\":0.4823829233646393}}";
private final static String ELLA_ENDPOINT = "/ella-web/api/v1/score";
private EllaService ellaService;
@Rule
public WireMockRule wireMockRule = new WireMockRule( wireMockConfig().dynamicPort() );
@Before
@SuppressWarnings( "resource" )
public void setup() {
int port = wireMockRule.port();
System.setProperty( "ella.uri", "http://localhost:" + port + ELLA_ENDPOINT );
System.setProperty( "ella.internal.customer.filter", String.valueOf( false ) );
System.setProperty( "ella.external.customer.filter", String.valueOf( false ) );
System.setProperty( "ella.shop.id.filter", "123456,56789,545334" );
ApplicationContext context = new AnnotationConfigApplicationContext( EllaConfiguration.class );
ellaService = context.getBean( EllaService.class );
}
@Test
public void testInvokeEllaCallsEllaWithRatepayHeadersAsyncCall() {
wireMockRule.stubFor( post( urlEqualTo( ELLA_ENDPOINT ) ).withHeader( ACCEPT, equalTo( APPLICATION_JSON_UTF8_VALUE ) )
.willReturn( okJson( ELLA_JSON_RESPONSE_FRAUD ) ) );
IrisBo irisBo = EllaTestDataProvider.createValidIrisBoWithRequest();
ellaService.invokeEllaAsync( irisBo );
verify( postRequestedFor( urlEqualTo( ELLA_ENDPOINT ) )
.withHeader( RatepayHeaders.HEADER_GATEWAY_REQUEST_ID, equalTo( EllaTestConstants.VALID_GATEWAY_ID ) )
.withHeader( RatepayHeaders.HEADER_TRANSACTION_ID, equalTo( EllaTestConstants.VALID_TRX_ID ) ) );
}
}
我得到下面提供的错误堆栈,
com.ratepay.iris.ella.dto.response.EllaGatewayUnsuccessfulResponseException: Problem deserializing property 'created' (expected type: [simple type, class java.time.LocalDate]; actual type: `java.time.OffsetDateTime`), problem: argument type mismatch
at [Source: (String)"{
"score": 707,
"reason": "DOMAIN_DOES_NOT_EXIST",
"riskBand": 4,
"email": {
"emailAddress": "fraudster@fraud.com",
"exists": 4,
"firstVerificationDate": "2019-05-31T19:08:20.7713155Z",
"firstVerificationDays": 0,
"totalHits": 31,
"uniqueHits": 1,
"score": {
"reason": "DOMAIN_DOES_NOT_EXIST",
"riskLevel": 6,
"relevantInfoId": 10900
}
},
"domain": {},
"phone": {},
"s"[truncated 1013 chars]; line: 57, column: 16] (through reference chain: com.ratepay.iris.ella.dto.response.EllaResponseDto["created"])
at com.ratepay.iris.ella.service.EllaService.invokeEllaAsync(EllaService.java:95)
at
com.ratepay.iris.ella.service.EllaServiceIntegrationTest.testInvokeEllaCallsEllaWithRatepayHeadersAsyncCall(EllaServiceIntegrationTest.java:108)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at com.github.tomakehurst.wiremock.junit.WireMockRule.evaluate(WireMockRule.java:73)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:139)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
at com.ratepay.commons.web.util.io.http.connector.RequestExecutor.createResponseWithBody(RequestExecutor.java:309)
at com.ratepay.commons.web.util.io.http.connector.RequestExecutor.createSucessfulResponse(RequestExecutor.java:298)
at com.ratepay.commons.web.util.io.http.connector.RequestExecutor.createResponse(RequestExecutor.java:284)
at com.ratepay.commons.web.util.io.http.connector.RequestExecutor.submit(RequestExecutor.java:123)
at com.ratepay.commons.web.util.io.http.connector.RequestExecutor.submitRequest(RequestExecutor.java:89)
at com.ratepay.commons.web.util.io.http.connector.ServiceConnector.doCall(ServiceConnector.java:210)
at com.ratepay.commons.web.util.io.http.connector.ServiceConnector.call(ServiceConnector.java:125)
at com.ratepay.iris.ella.service.EllaService.callEllaService(EllaService.java:128)
at com.ratepay.iris.ella.service.EllaService.invokeEllaAsync(EllaService.java:92)
它显然是由 ELLA_JSON_RESPONSE_FRAUD
中定义的返回响应的 + " \"created\": \"2019-05-31T19:08:20.7712944Z\",\n"
行构成的。
我提供了一个响应 DTO 示例来显示时间值定义,
@JsonInclude( JsonInclude.Include.NON_NULL )
@Getter
@Setter
public class EllaResponseDto extends BaseDto {
private String trackingId;
private Integer score;
private String reason;
private Integer riskBand;
private EmailDto email;
private DomainDto domain;
private PhoneDto phone;
private AddressDto shipAddress;
private AddressDto billingAddress;
private TransactionDto transaction;
private DeviceDto device;
private IpDto ip;
private ServiceDto service;
private String correlationId;
private String version;
@JsonDeserialize( using = JavaOffsetDateTimeDeserializer.class )
@JsonSerialize( using = JavaOffsetDateTimeSerializer.class )
private LocalDate created;
private EllaStatus status;
}
如果我正确理解问题,它在错误堆栈中表示为 Problem deserializing property 'created' (expected type: [simple type, class java.time.LocalDate]; actual type:
java.time.OffsetDateTime), problem: argument type mismatch
。
为了解决这种情况,我将创建日期定义为 private LocalDate created
,带有注释的序列化和反序列化选项。显然,这是行不通的。
我该如何解决这个问题?
@JsonDeserialize( using = JavaOffsetDateTimeDeserializer.class )
@JsonSerialize( using = JavaOffsetDateTimeSerializer.class )
private LocalDate created;
Deserializer 将字符串转换为 Offsetdatetime 但创建的数据类型是 LocalDate,我认为从测试数据“2019-05-31T19:08:20.7712944Z”(包括区域)来看,您应该使用 OffsetDateTime 而不是 LocalDate
我找到了解决问题的方法。我需要从
更改所有 DTO 类 的注释@JsonDeserialize( using = JavaOffsetDateTimeDeserializer.class )
@JsonSerialize( using = JavaOffsetDateTimeSerializer.class )
至
@JsonSerialize( using = LocalDateSerializer.class )
@JsonDeserialize( using = LocalDateDeserializer.class )
现在测试通过了。