这里是我的问题的简化版本。考虑以下REST服务...
@Stateless
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/test")
public class TestResource {
@POST
public Response test(Calendar c) {
System.out.println(c);
return Response.ok(Response.Status.OK).build();
}
@GET
@Path("/getCalendar")
public Response getCalendar() {
return Response.ok(toJSONString(Calendar.getInstance())).build();
}
public String toJSONString(Object object) {
GsonBuilder builder = new GsonBuilder();
builder.setDateFormat("yyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Gson gson = builder.create();
return gson.toJson(object);
}
}
当然,这个...
@ApplicationPath("/rest")
public class RestActivator extends Application {
}
我正在使用邮递员,起初我通过向'http://localhost:8080/ProjectName/rest/test/getCalendar'发送GET请求来获得Calendar对象的JSON表示形式。然后,我复制要返回的JSON,这是
{
"year": 2015,
"month": 5,
"dayOfMonth": 29,
"hourOfDay": 10,
"minute": 7,
"second": 24
}
然后使用邮递员,将上面返回给我的数据发送到POST到'http://localhost:8080/ProjectName/rest/'。然后会抛出“ javax.ws.rs.NotSupportedException:无法使用内容类型”。
如何解决此问题,以便该服务可以处理Calendar对象(以及将Calendar对象作为字段的类)?
编辑:
是,我正在设置正确的内容类型为application / json。
这是我得到的答复...
com.fasterxml.jackson.databind.JsonMappingException:无法从START_OBJECT令牌中反序列化java.util.Calendar的实例在[来源:io.undertow.servlet.spec.ServletInputStreamImpl@4cf87599;行:1,列:1]
更新:为了使其正常工作,我使用了@peeskillets解决方案。
Jackson通常仅适用于JavaBean样式的POJO,而Calendar
则不行。对于这些情况,Jackson允许我们创建自定义反序列化器。创建解串器后,可以在ObjectMapper
中将其注册到ContextResolver
中。例如
public class CalendarDeserializer extends JsonDeserializer<Calendar> {
@Override
public Calendar deserialize(JsonParser jp, DeserializationContext dc)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
int year = getInt("year", node);
int month = getInt("month", node);
int dayOfMonth = getInt("dayOfMonth", node);
int hourOfDay = getInt("hourOfDay", node);
int minute = getInt("minute", node);
int second = getInt("second", node);
Calendar c = Calendar.getInstance();
c.set(year, month, dayOfMonth, hourOfDay, minute, second);
return c;
}
private int getInt(String name, JsonNode node) {
return (Integer) ((IntNode) node.get(name)).numberValue();
}
}
我们可以通过ObjectMapper
进行注册
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Calendar.class, new CalendarDeserializer());
mapper.registerModule(module);
要在我们的JAX-RS应用程序中使用ObjectMapper
,我们可以在ContextResolver
中创建它,如here所示。如果尚未添加jackson-databind,则需要将其添加为依赖项。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson2.version}</version>
</dependency>
请注意,上述依赖关系已经随JAX-RS的Jackson JSON提供程序一起提供,因此,如果您已经具有Jackson JSON支持的依赖关系,则将不再需要它。
我已经使用您提供的JSON对它进行了测试,并且效果很好。
查看有关自定义解串器here的更多信息>
您需要在请求中传递正确的内容类型,并检查是否给出了正确的路径。
因此,在进行了一些研究之后,并感谢那些回答者(特别是@peeskillet,我为这个问题提出了两种解决方案。
我知道这是个老问题,但是我只是添加了一个长的而不是Calendar的构造函数,因此可以反序列化