When creating an Apache Wink REST service client in WebSphere Commerce v7.0 it is possible to use a custom entity provider with your REST service client allowing you to map a Java object to the service request and response.
NOTE: This post will build upon a previous post, Creating a REST Service Client in WebSphere Commerce v7.0 with Apache Wink, and will discuss how to add a custom entity provider to your REST service client.
Step 1. Create a Custom Entity Provider Class
To begin adding a custom entity provider to your Apache Wink REST service client, you first need to create a class that will implement one or both of the following interfaces to facilitate the conversion to and from a Java object.
- javax.ws.rs.ext.MessageBodyReader
- javax.ws.rs.ext.MessageBodyWriter
The sample class shown below will take a JSON response from a REST service and convert it into a Java object. For purposes of simplicity, I’ve only shown the MessageBodyReader implementation. This example shows a JSON object containing a single element (“ResultCode”) being transformed into a Java object of type CustomEntityResponse, containing a similarly named resultCode field.
package com.daharveyjr.commerce.avs.wink.providers; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.Provider; import org.apache.wink.common.model.json.JSONArray; import org.apache.wink.common.model.json.JSONException; import org.apache.wink.common.model.json.JSONFactory; import org.apache.wink.common.model.json.JSONObject; import org.apache.wink.common.utils.ProviderUtils; import com.daharveyjr.commerce.avs.wink.model.CustomEntityResponse; /** * @author daharveyjr */ @Provider public class CustomEntityProvider implements MessageBodyReader<CustomEntityResponse> { @Override public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2, MediaType arg3) { return true; } @Override public CustomEntityResponse readFrom(Class<CustomEntityResponse> arg0, Type arg1, Annotation[] arg2, MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5) throws IOException { CustomEntityResponse response = null; byte[] bytes = ProviderUtils.readFromStreamAsBytes(arg5); String bytesString = new String(bytes, ProviderUtils.getCharset(arg3)); try { System.setProperty( "org.apache.wink.common.model.json.factory.impl", "org.apache.wink.common.model.json.impl.ApacheJSONFactory" ); // Pull JSON Object :) JSONObject jsonObject = JSONFactory.newInstance().createJSONObject( bytesString); String resultCode = getStringValueFromJSONObject( jsonObject, "ResultCode"); if (resultCode != null && resultCode.equals("Success")) { response = new CustomEntityResponse(); response.setResultCode(resultCode); } else if (resultCode != null && resultCode.equals("Error")) { response = new CustomEntityResponse(); response.setResultCode(resultCode); } } catch (JSONException e) { e.printStackTrace(); response = null; } return response; } /** * @param elementName */ protected String getStringValueFromJSONObject(JSONObject jsonObject, String elementName) { String value = null; try { if (jsonObject != null && elementName != null && jsonObject.has(elementName)) { value = jsonObject.getString(elementName); } } catch (JSONException e) { e.printStackTrace(); value = null; } return value; } }
Step 2. Add an Application Object to the ClientConfig Object
Now to leverage the CustomEntityProvider class just created in the Apache Wink REST client, add an Application object, consisting of a Set containing the CustomEntityProvider Class object to your Apache Wink ClientConfig object.
Application clientApplication = new Application() { @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<Class<?>>(); classes.add(CustomEntityProvider.class); return classes; } }; clientConfig.applications(clientApplication);
Step 3. Pull the CustomEntityResponse Object from the ClientResponse Object
When pulling your response from the ClientResponse object, you’ll need to modify your code to pull the appropriate CustomEntityResponse object you created earlier.
CustomEntityResponse clientResponseObj = clientResponse.getEntity(CustomEntityResponse.class);
Step 4. Verify the Implementation
That’s it! Assuming you’ve properly implemented your Apache Wink REST service client, you should now be able to pull and retrieve your CustomEntityResponse object from your ClientResponse object!