Java Jackson LocalDate/Time反序列化

Java Jackson LocalDate/Time反序列化,java,jersey,jackson2,jersey-test-framework,Java,Jersey,Jackson2,Jersey Test Framework,我对jackson进行了配置,使其在java.time.LocalDate和java.time.LocalDateTime中提供了一个简单的字符串表示。这可以在序列化过程中找到,例如在RESTAPI上获取数据时 不过,反过来也不行。当我尝试将数据发送到服务器,并且JSON应该解析为java对象时,会引发此异常: javax.ws.rs.client.ResponseProcessingException:com.fasterxml.jackson.databind.JsonMappingExce

我对jackson进行了配置,使其在
java.time.LocalDate
java.time.LocalDateTime
中提供了一个简单的字符串表示。这可以在序列化过程中找到,例如在RESTAPI上获取数据时

不过,反过来也不行。当我尝试将数据发送到服务器,并且JSON应该解析为java对象时,会引发此异常:

javax.ws.rs.client.ResponseProcessingException:com.fasterxml.jackson.databind.JsonMappingException:无法构造java.time.LocalDateTime的实例:没有字符串参数构造函数/工厂方法从字符串值反序列化('2018-04-19T14:10:30.903'))

经过几个小时的研究,我成功地让它工作了,但只使用了我分别用
@jsondeseserialize(使用=LocalDateDeserializer.class)
@jsondeseserialize(使用=LocalDateTimeDeserializer.class)
注释的属性

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

ObjectMapper配置:

@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;
    }
}
长话短说:是否有一种全局定义映射的方法,这样我就不需要在每个字段上都使用这些注释。谢谢

编辑:

好的:我在没有注解的情况下用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);
    }
}

您通过
JerseyTest
configure()
方法向服务器注册了
ContextResolver
,但是如果查看异常,您将看到这是客户端异常(请注意包名中的
client
)。所以问题出在客户端。您缺少的是,反序列化还需要在客户端进行,从JSON到
Poc
,因此还需要在客户端注册
ContextResolver
。为此,您可以覆盖
JerseyTest
上的
configureClient()
,并在那里注册
ContextResolver

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

mapper.registerModule(新的JavaTimeModule())应该足够了。与我的问题相关:我在这上面浪费了一整天的时间,在使用Jersey测试框架时,处理了无数其他无法开箱即用的事情。最后,这是丢失的最后一块,非常感谢。
@Override
public void configureClient(ClientConfig config) {
    config.register(ObjectMapperContextResolver.class);
}