2016-09-08 64 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。 –