我配置了jackson,以便在java.time.LocalDate
和java.time.LocalDateTime
时为我提供一个smiple字符串表示。这可以在序列化过程中找到,例如当我在REST api上获取数据时。
但它反过来却不起作用。当我尝试将数据发送到服务器并且应该将JSON解析为java对象时抛出此异常:
javax.ws.rs.client.ResponseProcessingException:com.fasterxml.jackson.databind.JsonMappingException:无法构造java.time.LocalDateTime的实例:no String-argument构造函数/工厂方法从String值反序列化('2018 -04-19T14:10:30.903' )
经过几个小时的研究后,我设法让它工作,但只有我分别用@JsonDeserialize(using = LocalDateDeserializer.class)
或@JsonDeserialize(using = 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;
}
}
我尝试将自定义反序列化器添加到JavaTimeModule,但没有成功:
JavaTimeModule dateTimeModule = new JavaTimeModule();
dateTimeModule.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE);
dateTimeModule.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
mapper.registerModule(dateTimeModule);
长话短说:有没有办法全局定义映射,所以我不需要在每个字段上都有这些注释。谢谢!
修改
好吧:我用邮递员测试了它,没有注释,它按预期工作。但是,当我运行单元测试(JerseyTest)时,它会抛出上述异常。我将ObjectMapperContextResolver
注册到测试应用程序,但可能是我遗漏了一些东西。
很抱歉没有提到我参加了单元测试。
识别TestClass:
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);
}
}
答案 0 :(得分:2)
您通过ContextResolver
的{{1}}方法向服务器注册了configure()
,但是如果查看异常,您会发现这是客户端异常(通知包名称中的JerseyTest
。所以问题出在客户端。您缺少的是反序列化也需要在客户端从JSON发生到client
,因此您还需要在客户端上注册Poc
。为此,您可以覆盖ContextResolver
上的configureClient()
并在那里注册JerseyTest
。
ContextResolver