【问题标题】:How to pass raw JSON via Jackson?如何通过杰克逊传递原始 JSON?
【发布时间】:2023-04-06 23:43:01
【问题描述】:

我们有一整套 JAX-RS REST 服务在 Apache CXF 和 Jackson 之上运行。 我们使用 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) 添加到对象映射器中,但没有任何效果。唯一可行的是,如果我将媒体类型设置为纯字符串,这绕过了杰克逊,但不好,因为我返回了错误的内容类型

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

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

【问题讨论】:

  • 我不得不改用 Map 并让 Jersey 正确解析它...我添加了 JacksonJsonProvider 和 mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

标签: java json cxf jax-rs jackson


【解决方案1】:

终于找到了解决办法。诀窍是扩展 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;
    }
}

完美运行。

【讨论】:

  • 我现在也面临同样的问题...您能否提供解决问题的 JacksonJsonProvider 示例?
  • 我应该在哪里添加它???我注册了我的提供程序,但尚未工作... 2013 年 12 月 14 日上午 8:49:11 com.sun.jersey.api.core.ScanningResourceConfig logClasses 信息:找到提供程序类:com.wordnik.swagger.jersey 类。 Listing.JerseyApiDeclarationProvider 类 com.tools.web.handler.JacksonJsonProvider
【解决方案2】:

ObjectMapper 不工作?应该只是:

ObjectMapper mapper = new ObjectMapper()
MyObj obj = MyObj();
...set values...
String jsonRes = mapper.writeValueAsString(obj);
return Response.ok(jsonRes, MediaType.APPLICATION_JSON).build();

【讨论】:

  • 不。它仍然在某处转换它,并且字符串在响应中转义。
【解决方案3】:

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

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

【讨论】:

  • 不起作用。如果我返回字符串,杰克逊仍然会逃避它,例如"{\"test\":1}"
  • 哪个版本? 2.0.2 应该以这种方式工作(在 2.0.0 中有一个小故障,这可能与此处相关);以及 1.9.x.
猜你喜欢
  • 1970-01-01
  • 2018-06-07
  • 1970-01-01
  • 2015-11-23
  • 2016-07-20
  • 1970-01-01
  • 2019-05-02
  • 2014-02-12
相关资源
最近更新 更多