We have a whole set of JAX-RS REST services running on top of Apache CXF and Jackson. We use JAXB annotations to take care of marshalling POJOs to JSON, works great.
我们在Apache CXF和Jackson之上运行了一整套JAX-RS REST服务。我们使用JAXB注释来处理将POJO编组为JSON,效果很好。
However, we have one or two places where we want to return raw JSON string (that we fetch from a Redis cache).
但是,我们有一两个地方要返回原始JSON字符串(我们从Redis缓存中获取)。
Jackson always wraps the string in double quotes and escapes all the double quotes in it, e.g.
杰克逊总是将字符串用双引号括起来,并将其中的所有双引号括起来,例如
@GET @Produces("application/json")
public Response getData() {
String json = ...get from Redis...
return Response.ok(json,"application/json").build()
}
gives us
给我们
"{\"test\":1}"
instead of
代替
{"test":1}
I've tried multiple things, adding RawSerializer(String.class) to the Object mapper, nothing works. The only thing that works is if I set the media type to plain string, which bypassed Jackson, but is not good, since I am returning the wrong content type
我尝试过多种方法,将RawSerializer(String.class)添加到Object映射器中,没有任何效果。唯一有效的是,如果我将媒体类型设置为普通字符串,绕过杰克逊,但是不好,因为我返回了错误的内容类型
i.e.
即
return Response.ok(json,"text/plain").build()
works, but poorly (wrong content type, which screws up .Net WCF apps that call us)
工作,但很差(错误的内容类型,这搞砸了.Net WCF应用程序打电话给我们)
3 个解决方案
#1
10
Found the solution finally. The trick was to extend the JacksonJsonProvider (which we use in CXF to force it to use Jackson instead of Jettison) and tell it to bypass Jackson altogether when dealing with raw Strings:
最后找到了解决方案。诀窍是扩展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;
}
}
Works perfectly.
完美的工作。
#2
0
ObjectMapper isn't working? Should just be:
ObjectMapper不工作?应该只是:
ObjectMapper mapper = new ObjectMapper()
MyObj obj = MyObj();
...set values...
String jsonRes = mapper.writeValueAsString(obj);
return Response.ok(jsonRes, MediaType.APPLICATION_JSON).build();
#3
0
In such case, your best bet is to use return type of String
, since the issue is not with Jackson -- whose job is to produce JSON out of Objects, not pass Strings as is -- but with JAX-RS which is not to call Jackson. Default Jackson-backed JSON provider will pass String
value exactly as is (ditto for byte[]
), without any processing.
在这种情况下,你最好的选择是使用返回类型的String,因为问题不在于Jackson - 其工作是从对象生成JSON,而不是按原样传递字符串 - 但是使用JAX-RS不是叫杰克逊。默认的Jackson支持的JSON提供程序将完全按原样传递String值(对于byte []来说是ditto),无需任何处理。
For what it is worth, there is actually JsonGenerator.writeRaw()
method as well, which allows embedding literal text in OutputStream
, but JAX-RS implementations use ObjectMapper
, not low-level abstractions.
对于它的价值,实际上还有JsonGenerator.writeRaw()方法,它允许在OutputStream中嵌入文字文本,但JAX-RS实现使用ObjectMapper,而不是低级抽象。
#1
10
Found the solution finally. The trick was to extend the JacksonJsonProvider (which we use in CXF to force it to use Jackson instead of Jettison) and tell it to bypass Jackson altogether when dealing with raw Strings:
最后找到了解决方案。诀窍是扩展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;
}
}
Works perfectly.
完美的工作。
#2
0
ObjectMapper isn't working? Should just be:
ObjectMapper不工作?应该只是:
ObjectMapper mapper = new ObjectMapper()
MyObj obj = MyObj();
...set values...
String jsonRes = mapper.writeValueAsString(obj);
return Response.ok(jsonRes, MediaType.APPLICATION_JSON).build();
#3
0
In such case, your best bet is to use return type of String
, since the issue is not with Jackson -- whose job is to produce JSON out of Objects, not pass Strings as is -- but with JAX-RS which is not to call Jackson. Default Jackson-backed JSON provider will pass String
value exactly as is (ditto for byte[]
), without any processing.
在这种情况下,你最好的选择是使用返回类型的String,因为问题不在于Jackson - 其工作是从对象生成JSON,而不是按原样传递字符串 - 但是使用JAX-RS不是叫杰克逊。默认的Jackson支持的JSON提供程序将完全按原样传递String值(对于byte []来说是ditto),无需任何处理。
For what it is worth, there is actually JsonGenerator.writeRaw()
method as well, which allows embedding literal text in OutputStream
, but JAX-RS implementations use ObjectMapper
, not low-level abstractions.
对于它的价值,实际上还有JsonGenerator.writeRaw()方法,它允许在OutputStream中嵌入文字文本,但JAX-RS实现使用ObjectMapper,而不是低级抽象。