JAX-RS和java.time.LocalDate作为输入参数
使用JAX-RS和java.time.LocalDate
(java8)时出现问题。
我想使用JSON将这样的对象传递给JAX-RS方法:
Person { java.time.LocalDate birthDay; }
我得到的例外是:
com.fasterxml.jackson.databind.JsonMappingException
:找不到类型[simple type,classjava.time.LocalDate
]的合适构造函数:无法在[Source:io.undertow.servlet.spec.ServletInputStreamImpl@21cca2c1
]中实例化JSON对象(需要添加/启用类型信息?)io.undertow.servlet.spec.ServletInputStreamImpl@21cca2c1
; line:2,column:3]
如何创建某种将json-dates映射到java.time.LocalDate
的拦截器? 我已经尝试实现了一个MessageBodyReader
,但是如果LocalDate
是另一个类中的一个字段 ,我必须为每个持有LocalDate
类编写一个MessageBodyReader
(据我所知)。
(Java EE7(仅使用javaee-api,不需要任何第三方依赖),JAX-RS,Java 8,Wildfly 8.2)
有什么建议么?
通常我会说为Jackson编写一个Serializer / Deserializer,但由于你不想要任何其他依赖,你可以使用JAXB解决方案。 Jackson(带有Resteasy)支持JAXB注释。 所以我们能做的就是编写一个XmlAdapter
来从String转换为LocalDate
。 一个例子就是这样的
import java.time.LocalDate; import java.time.format.DateTimeFormatter; import javax.xml.bind.annotation.adapters.XmlAdapter; public class LocalDateAdapter extends XmlAdapter { @Override public LocalDate unmarshal(String dateString) throws Exception { return LocalDate.parse(dateString, DateTimeFormatter.ISO_DATE); } @Override public String marshal(LocalDate localDate) throws Exception { return DateTimeFormatter.ISO_DATE.format(localDate); } }
你可以选择你想要的任何格式,我只使用了DateTimeFormatter.ISO_DATE
,它基本上会查找这种格式(2011-12-03)。
然后,您需要做的就是为该类型的getter注释该字段
public class Person { private LocalDate birthDate; @XmlJavaTypeAdapter(LocalDateAdapter.class) public LocalDate getBirthDate() { return birthDate; } public void setBirthDate(LocalDate birthDate) { this.birthDate = birthDate; } }
如果您不希望使用此批注来混淆模型类,则可以在包级别简单地声明批注。
在与模型类相同的包中的package-info.java
文件中,添加它
@XmlJavaTypeAdapters({ @XmlJavaTypeAdapter(type = LocalDate.class, value = LocalDateAdapter.class) }) package thepackage.of.the.models; import java.time.LocalDate; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
测试
@Path("/date") public class DateResource { @POST @Consumes(MediaType.APPLICATION_JSON) public Response postPerson(Person person) { return Response.ok(DateTimeFormatter.ISO_DATE.format( person.getBirthDate())).build(); } } @Test public void testResteasy() throws Exception { WebTarget target = client.target( TestPortProvider.generateURL(BASE_URI)).path("date"); String person = "{\"birthDate\":\"2015-01-04\"}"; Response response = target.request().post(Entity.json(person)); System.out.println(response.readEntity(String.class)); response.close(); }
结果: 2015-01-04
UPDATE
同样对于jackson(我知道OP说没有依赖关系,但这是针对其他人的),你可以使用jackson-datatype-jsr310模块。 在此查看完整解决方案