2016-09-08 42 views
0

我正在使用RESTEasy客戶端從API中檢索JSON字符串。該JSON有效載荷看起來是這樣的:在RESTEasy客戶端中提取JSON響應的特定節點

{ 
    "foo1" : "", 
    "foo2" : "", 
    "_bar" : { 
    "items" : [ 
     { "id" : 1 , "name" : "foo", "foo" : "bar" }, 
     { "id" : 2 , "name" : "foo", "foo" : "bar" }, 
     { "id" : 3 , "name" : "foo", "foo" : "bar" }, 
     { "id" : 4 , "name" : "foo", "foo" : "bar" } 
    ] 
    } 
} 

現在,我想只提取對象映射items節點。攔截JSON響應主體並將其修改爲具有items作爲根節點的最佳方式是什麼?

我爲我的API方法使用了RESTEasy proxy framework

的REST客戶端代碼:

ResteasyWebTarget target = client.target("https://"+server); 
target.request(MediaType.APPLICATION_JSON); 
client.register(new ClientAuthHeaderRequestFilter(getAccessToken())); 
MyProxyAPI api = target.proxy(MyProxyAPI.class); 
MyDevice[] result = api.getMyDevice(); 

的RESTEasy代理接口:

public interface MyProxyAPI { 

    @GET 
    @Produces(MediaType.APPLICATION_JSON) 
    @Path("/device") 
    public MyDevice[] getMyDevices(); 

    ... 
} 
+0

轉換爲JavaScript對象和檢索它作爲一個對象。 – SaviNuclear

+0

「items」是根源,還是僅僅是你不想映射消息的任何其他元素是重要的?快速查看RestEasy文檔,您是通過JAXB提供程序對Java bean進行自動編組/解組嗎? – dbreaux

+0

@dbreaux是的,我只是不想映射任何其他元素。查看我對OP編輯的簡化實現代碼。我當然可以註冊一個提供者來改變消息體,但是我想知道這樣的提供者的實現是怎麼樣的。 –

回答

1

您可以創建一個ReaderInterceptor並用傑克遜來操縱你的JSON:

public class CustomReaderInterceptor implements ReaderInterceptor { 

    private ObjectMapper mapper = new ObjectMapper(); 

    @Override 
    public Object aroundReadFrom(ReaderInterceptorContext context) 
         throws IOException, WebApplicationException { 

     JsonNode tree = mapper.readTree(context.getInputStream()); 
     JsonNode items = tree.get("_bar").get("items"); 
     context.setInputStream(new ByteArrayInputStream(mapper.writeValueAsBytes(items))); 
     return context.proceed(); 
    } 
} 

然後註冊在您的Client中創建的ReaderInterceptor

Client client = ClientBuilder.newClient(); 
client.register(CustomReaderInterceptor.class); 
+1

實際上,您對另一個問題的答案之一可能是一個簡單的解決方案:http://stackoverflow.com/a/38352932/796761 – dbreaux

+0

@dbreaux感謝您提醒我:) –

+1

您的舊解決方案由dbreaux (獲取JSON並通過Jackson樹訪問所需的節點)是我到目前爲止的解決方案。這當然不適用於代理框架。我會嘗試攔截器。謝謝。 –

1

我有同樣的願望,不必爲包含比我關心的字段更多的字段的消息定義複雜的Java類。在我的JEE服務器(WebSphere)中,Jackson是底層的JSON實現,它似乎是RESTEasy的一個選項。傑克遜有一個@JsonIgnoreProperties註釋,可以忽略未知的JSON字段:

import javax.xml.bind.annotation.XmlType; 
import org.codehaus.jackson.annotate.JsonIgnoreProperties; 

@XmlType 
@JsonIgnoreProperties(ignoreUnknown = true) 
public class JsonBase {} 

我不知道其他的JSON實現具有類似的功能,但它肯定似乎是一個自然的用例。

(我也寫一個有關用blog post這和其他一些JAX-RS技術,以我的WebSphere環境。)

+0

這是一個很好的解決方案,但它可能無法適用於OP描述的情況。 'items'節點是'_bar'的子節點,而不是根節點的子節點。 –

+0

你仍然可以通過定義幾乎沒有任何內容的包裝類來做到這一點。就我而言,這比替代品更好。 – dbreaux

+0

有道理。 Upvoted。 –