JAX-RS / Jersey ".get(Integer.class)"和单个 JSON 基元(整数)值?



我有一个具有以下方法的JAX-RS WebService:

@Path("/myrest")
public class MyRestResource {
...
    @GET
    @Path("/getInteger")
    @Produces(APPLICATION_JSON)
    public Integer getInteger() {
        return 42;
    }

@Test
public void testGetPrimitiveWrapers() throws IOException {
    // this works:
    assertEquals(new Integer(42), new ObjectMapper().readValue("42", Integer.class));
    // that fails:
    assertEquals(new Integer(42), resource().path("/myrest/getInteger").get(Integer.class));
}

我得到以下异常:

com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: A message body reader for Java class java.lang.Integer, and Java type class java.lang.Integer, and MIME media type application/json was not found
com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are: application/json
...

问题只是返回单个原始值(int/boolean)或它们的包装类。返回其他POJO类不是问题,所以我猜所有关于JSONConfiguration的答案。FEATURE_POJO_MAPPING和JAXB注释在这里不适用。或者,如果不能访问返回类型,应该使用哪个注释来描述返回类型类源?

使用ngrep我可以验证只有字符串"42"是由webservice返回的。根据规范,这是一个有效的JSON"值",但不是一个有效的JSON"文本"。所以我的问题是在客户端还是服务器端?

我尝试根据http://tugdualgrall.blogspot.de/2011/09/jax-rs-jersey-and-single-element-arrays.html激活JSONConfiguration natural/badgerfish,但没有成功(ngrep仍然显示"42")。这是正确的道路吗?

任何想法都是赞赏的!

这是Jackson中一个公认的bug,它被吹捧为一个特性(在我看来是错误的)。为什么我认为它是一个bug?因为虽然序列化可以工作,但反序列化肯定不行。

在任何情况下,有效的JSON不能从当前返回类型生成,所以我建议创建一个包装器类:

class Result<T> {
    private T data;
    // constructors, getters, setters
}
@GET
@Path("/getInteger")
@Produces(APPLICATION_JSON)
public Result<Integer> getInteger() {
    return new Result<Integer)(42);
}

或者,您可以选择包装根值,这将自动将您的数据封装在一个顶级JSON对象中,由对象的简单类型名称作为关键字-但请注意,如果使用此选项,所有生成的JSON将被包装(不仅仅是原语):

final ObjectMapper mapper = new ObjectMapper()
    .configure(SerializationFeature.WRAP_ROOT_VALUE, true)
    .configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
final String serializedJson = mapper.writeValueAsString(42);
final Integer deserializedVal = mapper.readValue(serializedJson,
        Integer.class);
System.out.println(serializedJson);
System.out.println("Deserialized Value: " + deserializedVal);
输出:

{"整数":42}
反序列化值:42

有关如何在JAX-RS环境中检索和配置ObjectMapper实例的详细信息,请参阅此回答。

最新更新