gpt4 book ai didi

java - Jackson LocalDate/Time 反序列化

转载 作者:搜寻专家 更新时间:2023-11-01 02:57:37 27 4
gpt4 key购买 nike

我配置了 jackson,如果 java.time.LocalDatejava.time.LocalDateTime,它会给我一个简单的字符串表示。这在序列化过程中有效,例如,当我在 REST api 上获取数据时。

但反之则不行。当我尝试将数据发送到服务器并且应该将 JSON 解析为 java 对象时,会抛出此异常:

javax.ws.rs.client.ResponseProcessingException: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.time.LocalDateTime: no String-argument constructor/factory method to deserialize from String value ('2018-04-19T14:10:30.903')

经过几个小时的研究,我设法让它工作,但只使用了我用 @JsonDeserialize(using = LocalDateDeserializer.class)@JsonDeserialize(using = LocalDateTimeDeserializer.class)

在我看来,如果我可以在一个中心位置定义这些映射,那将是最理想的。

对象映射器配置:

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
@Override
public ObjectMapper getContext(Class<?> aClass) {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

return mapper;
}
}

我尝试将自定义反序列化器添加到 JavaTimeModule,但没有成功:

JavaTimeModule dateTimeModule = new JavaTimeModule();
dateTimeModule.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE);
dateTimeModule.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);

mapper.registerModule(dateTimeModule);

长话短说:有没有一种方法可以全局定义映射,这样我就不需要在每个字段上都使用这些注释。谢谢!

编辑:

好吧:我用 postman 测试了它,没有注释,它按预期工作。但是,当我运行单元测试 (JerseyTest) 时,它会抛出上述异常。我将 ObjectMapperContextResolver 注册到测试应用程序,但可能我遗漏了一些东西。

很抱歉没有提到我在单元测试中。

测试类:

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

import javax.ws.rs.core.Application;

import java.time.LocalDate;
import java.time.LocalDateTime;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;


public class PocRestTest extends JerseyTest {

private static PocService mockedPocService;

@Override
protected Application configure() {
mockedPocService = Mockito.mock(PocService.class);
ResourceConfig config = new ResourceConfig();
config.register(new PocRest(mockedPocService));
config.register(ObjectMapperContextResolver.class);
return config;
}

private Poc dto;

@Before
public void init() {
dto = new Poc();
dto.setId(1);
dto.setName("hi rest");
dto.setDate(LocalDate.now());
dto.setDateTime(LocalDateTime.now());

doReturn(dto).when(mockedPocService).getPocById(1);
}

@Test
public void test() {
Poc response = target("poc/1").request().get(Poc.class);
assertEquals(dto.getId(), response.getId());
assertEquals(dto.getName(), response.getName());
assertEquals(dto.getDate(), response.getDate());
assertEquals(dto.getDateTime(), response.getDateTime());

verify(mockedPocService).getPocById(1);
verifyNoMoreInteractions(mockedPocService);
}
}

最佳答案

您通过 JerseyTestconfigure() 方法向服务器注册了 ContextResolver,但是如果您查看异常,您''ll see that is a client side exception(注意包名称中的 client)。所以问题出在客户端。你缺少的是反序列化也需要在客户端发生,从 JSON 到 Poc,所以你还需要在客户端注册 ContextResolver。为此,您可以覆盖 JerseyTest 上的 configureClient() 并在那里注册 ContextResolver

@Override
public void configureClient(ClientConfig config) {
config.register(ObjectMapperContextResolver.class);
}

关于java - Jackson LocalDate/Time 反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49921346/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com