I'm retrieving a JSON string from an API using a RESTEasy client. The JSON payload looks something like this:
{
"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 RESTEasy proxy framework for my API methods.
The REST client code:
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:
public interface MyProxyAPI {
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/device")
public MyDevice[] getMyDevices();
...
}
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 @JsonIgnoreProperties annotation that can ignore unknown JSON fields:
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 blog post with this and some other JAX-RS techniques relevant to my WebSphere environment.)
You could create a ReaderInterceptor
and use Jackson to manipulate your 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();
}
}
Then register the ReaderInterceptor
created above in your Client
:
Client client = ClientBuilder.newClient();
client.register(CustomReaderInterceptor.class);