36793

Extract specific node of JSON response in RESTEasy Client

Question:

I'm retrieving a JSON string from an API using a RESTEasy client. The JSON payload looks something like this:

<pre class="lang-json prettyprint-override">{ "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" } ] } }

Now I'd like to extract only the items node for object mapping. What is the best way to intercept the JSON response body and modify it to have items as root node?

I'm using the <a href="https://docs.jboss.org/resteasy/docs/3.0-beta-3/userguide/html/RESTEasy_Client_Framework.html#d4e2049" rel="nofollow">RESTEasy proxy framework</a> for my API methods.

The REST client code:

<pre class="lang-java prettyprint-override">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 proxy interface:

<pre class="lang-java prettyprint-override">public interface MyProxyAPI { @GET @Produces(MediaType.APPLICATION_JSON) @Path("/device") public MyDevice[] getMyDevices(); ... }

Answer1:

I had the same desire to not have to define complex Java classes for messages that contain way more fields than I care about. In my JEE server (WebSphere), Jackson is the underlying JSON implementation, which does appear to be an option with RESTEasy. Jackson has an <a href="http://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonIgnoreProperties.html" rel="nofollow">@JsonIgnoreProperties</a> annotation that can ignore unknown JSON fields:

<pre class="lang-java prettyprint-override">import javax.xml.bind.annotation.XmlType; import org.codehaus.jackson.annotate.JsonIgnoreProperties; @XmlType @JsonIgnoreProperties(ignoreUnknown = true) public class JsonBase {}

I don't know if other JSON implementations have a similar capability, but it certainly seems a natural use-case.

(I also wrote a <a href="https://www.ibm.com/developerworks/community/blogs/Dougclectica/entry/A_JSON_REST_client_in_WebSphere_8_5_Full_Profile" rel="nofollow">blog post</a> with this and some other JAX-RS techniques relevant to my WebSphere environment.)

Answer2:

You could create a <a href="https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/ReaderInterceptor.html" rel="nofollow">ReaderInterceptor</a> and use Jackson to manipulate your JSON:

<pre class="lang-java prettyprint-override">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(); } }

Then register the <a href="https://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/ReaderInterceptor.html" rel="nofollow">ReaderInterceptor</a> created above in your <a href="https://docs.oracle.com/javaee/7/api/javax/ws/rs/client/Client.html" rel="nofollow">Client</a>:

<pre class="lang-java prettyprint-override">Client client = ClientBuilder.newClient(); client.register(CustomReaderInterceptor.class);

Recommend

  • Getting a null exception as model in razor
  • XMLHttpRequest().send() not working in chrome and opera
  • iOS Bluetooth LE cant get notification programatically but can in other apps
  • Dropbox Java: Use Proxy with authentication
  • phonegap plugin for select a video from the library
  • Spring Boot multipart content type HTTP Request using RestTemplate
  • Convert and save string to binary file in Python
  • Restful Services: Sending HTTP 405 instead of HTTP 500 error
  • jersey rest services showing exception javax.ws.rs.WebApplicationException: javax.xml.bind.MarshalEx
  • BufferCB not being called by SampleGrabber
  • WebMvcTest in Spring Boot
  • How to convert CMSampleBuffer to Data in Swift?
  • No default constructor found exception
  • Spring HttpMessageNotReadableException
  • 404 response on simple RESTeasy example with Tomcat
  • How does SSH Window Size affect in paramiko
  • File download through ajax
  • AS3 Flash/AIR recording video with webcam and save it
  • How to insert alt tags dynamically in jsp
  • Is it possible to use an http url as your source location of a Source Filter in DirectShow .Net?
  • Comparing user's facebook/twitter friends to site's users in Python/Django
  • Why can't UI components be accessed from a backgroundworker?
  • Firefox Extension - Monitor refresh and change of tab
  • How to attach a node.js readable stream to a Sendgrid email?
  • C# - Serializing and deserializing static member
  • Hazelcast - OperationTimeoutException
  • RestKit - RKRequestDelegate does not exist
  • php design question - will a Helper help here?
  • Cannot Parse HTML Data Using Android / JSOUP
  • Revoking OAuth Access Token Results in 404 Not Found
  • AngularJs get employee from factory
  • JTable with a ScrollPane misbehaving
  • Java static initializers and reflection
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Authorize attributes not working in MVC 4
  • unknown Exception android
  • Observable and ngFor in Angular 2
  • failed to connect to specific WiFi in android programmatically
  • Unable to use reactive element in my shiny app
  • How can I use threading to 'tick' a timer to be accessed by other threads?