14

我们有一整套在 Apache CXF 和 Jackson 之上运行的 JAX-RS REST 服务。我们使用 JAXB 注释来处理将 POJO 编组为 JSON,效果很好。

但是,我们有一两个地方想要返回原始 JSON 字符串(我们从 Redis 缓存中获取)。

Jackson 总是将字符串用双引号括起来并转义其中的所有双引号,例如

@GET @Produces("application/json")
public Response getData() {

    String json = ...get from Redis...
    return Response.ok(json,"application/json").build() 
}

给我们

"{\"test\":1}"

代替

{"test":1}

我尝试了多种方法,将 RawSerializer(String.class) 添加到对象映射器中,但没有任何效果。唯一有效的是,如果我将媒体类型设置为纯字符串,这绕过了杰克逊,但不好,因为我返回了错误的内容类型

IE

return Response.ok(json,"text/plain").build() 

有效,但效果不佳(错误的内容类型,这会破坏调用我们的 .Net WCF 应用程序)

4

3 回答 3

10

终于找到了解决办法。诀窍是扩展 JacksonJsonProvider(我们在 CXF 中使用它来强制它使用 Jackson 而不是 Jettison)并告诉它在处理原始字符串时完全绕过 Jackson:

public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType){
    if (String.class.equals(type)) {
        //pass strings as-is, they are most likely cached JSON responses
        return false;
    } else {
        return true;
    }
}

完美运行。

于 2012-05-18T13:26:42.533 回答
0

在这种情况下,您最好的选择是使用返回类型 of String,因为问题不在于杰克逊——他的工作是从对象中生成 JSON,而不是按原样传递字符串——而是使用不调用的 JAX-RS杰克逊。默认的 Jackson 支持的 JSON 提供程序将String完全按原样传递值(同上byte[]),无需任何处理。

值得一提的是,实际上还有JsonGenerator.writeRaw()一种方法,它允许在 中嵌入文字文本OutputStream,但 JAX-RS 实现使用ObjectMapper,而不是低级抽象。

于 2012-05-18T03:57:12.437 回答
0

对象映射器不工作?应该只是:

ObjectMapper mapper = new ObjectMapper()
MyObj obj = MyObj();
...set values...
String jsonRes = mapper.writeValueAsString(obj);
return Response.ok(jsonRes, MediaType.APPLICATION_JSON).build();
于 2012-05-17T20:55:32.057 回答