2012-05-17 55 views
12

我們有一整套運行在Apache CXF和Jackson上的JAX-RS REST服務。 我們使用JAXB註釋來處理將JSON編組爲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應用程序,打電話給我們)

+0

我不得不使用地圖,讓澤西正確解析它...我添加了JacksonJsonProvider與mapper.setVisibility(PropertyAccessor.FIELD,Visibility.ANY); –

回答

0

ObjectMapper不工作?應該僅僅是:

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

沒有。它仍然會將其轉換到某個位置,並且字符串在響應中出現。 –

0

在這種情況下,最好的辦法是使用String返回類型,因爲這個問題是不是與傑克遜 - 他的工作就是生產出的JSON對象,不通過字符串作爲是 - 但是JAX-RS不打給傑克遜。傑克遜支持的默認JSON提供商將完全按原樣傳遞String值(同上byte[]),而不進行任何處理。

對於什麼是值得的,有實際JsonGenerator.writeRaw()方法爲好,這使得在OutputStream嵌入文字文本,但是JAX-RS實現使用ObjectMapper,而不是低層次的抽象。

+0

不起作用。如果我返回字符串,傑克遜仍然逃脫它,例如 「{\」test \「:1}」 –

+0

哪個版本? 2.0.2應該以這種方式工作(在2.0.0中有一個小故障,這可能與此有關);以及1.9.x. – StaxMan

10

最後找到解決方案。訣竅是延長JacksonJsonProvider(我們將在CXF使用強制使用傑克遜,而不是拋棄),並告訴它與原始字符串打交道時完全繞過傑克遜:

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; 
    } 
} 

完美的作品。

+0

我現在面臨同樣的問題......你能否提供JacksonJsonProvider解決問題的例子? –

+0

我應該在哪裏添加它?我有我的供應商註冊,但尚未workign ... 2013年12月14日上午8時49分11秒com.sun.jersey.api.core.ScanningResourceConfig logClasses 信息:提供者類找到: 類com.wordnik.swagger。 jersey.listing。JerseyApiDeclarationProvider class com.tools.web.handler.JacksonJsonProvider –