Calling a Watson service in Java

Overview

Note: this API needs to be updated to v2. Identify is now a resource on the Language Translation API.
http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/language-translation/api/v2/

Making an HTTP REST API POST request in Java is in principle as simple this:
Request request = Request.Post(serviceURI)
.addHeader("Authorization", basicAuthorization)
.bodyString(body, ContentType.APPLICATION_FORM_URLENCODED);
Executor executor = Executor.newInstance();
String response = executor.execute(request).returnContent().asString();

This code, uses the Apache Fluent API, which exposes only the essentials of the Apache HTTPClient.

The Authorization header is required for authentication by the Watson API, and is a base64 encoded string.
String auth = username + ":" + password;
String basicAuthorization = "Basic "+ Base64.encodeBase64String(auth.getBytes());

The POST request is “x-www-form-urlencoded” and in Java consists of a List<NameValuePair>:
List<NameValuePair> params = new ArrayList<NameValuePair>();

Call the Language Identification API

To call a specific Watson API like the Language Identification API, use above code and add the required parameters. In this case, the sid, txt parameters are required, with a rt optional parameter.

The complete class for a web service in WebSphere, calling the Language Identification API would look like this:

package com.remkohde.dev.bluemix;
 
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
 
import javax.ws.rs.GET;
import javax.ws.rs.Path;
 
import com.ibm.json.java.JSONObject;
 
import org.apache.commons.codec.binary.Base64;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.ContentType;
 
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
 
@Path("/languageidentification")
public class LanguageIdentificationResource {
  @GET
  @Produces(MediaType.APPLICATION_JSON)
  public Response getInformation() {
   String json = "";
   try {
    String username = "username from binded service credentials";
    String password = "password from binded service credentials";
    String baseURL = "https://gateway.watsonplatform.net/language-identification-beta/api";
    String sid = "lid-generic";
    String returnType = "json";
    String text = "Hello, what language is this question in?";
 
    URI serviceURI = new URI(baseURL).normalize();
 
    String auth = username + ":" + password;
    String basicAuthorization = "Basic "+ Base64.encodeBase64String(auth.getBytes());
 
    List params = new ArrayList();
    params.add(new BasicNameValuePair("txt",text));
    params.add(new BasicNameValuePair("sid",sid));
    params.add(new BasicNameValuePair("rt",returnType));
 
    String body = URLEncodedUtils.format(params, "utf-8");
 
    Request request = Request.Post(serviceURI)
     .addHeader("Authorization", basicAuthorization)
     .bodyString(body, ContentType.APPLICATION_FORM_URLENCODED);
 
    Executor executor = Executor.newInstance();
    String response = executor.execute(request).returnContent().asString();
 
    JSONObject lang = JSONObject.parse(response);
    json = lang.toString();
 
   }catch(URISyntaxException use){
    String error = use.getMessage()+",\n Reason: "+use.getReason();
    json = "{\"error\":\""+error+"\"}";
   }catch(IOException ioe){
    String error = ioe.getMessage();
    json = "{\"error\":\""+error+"\"}";
   }
   return Response.ok(json).build();
  }
}

Notes on the configuration and annotation

I built this application using the Java DB Web Starter boilerplate in Bluemix. If you need help setting it up, let me know via http://www.twitter.com/remkohdev.

This class uses the following dependencies:

  • com.ibm.websphere.appserver.api.json_1.0.2.jar
  • com.ibm.ws.javaee.jaxrs.1.1_1.0.1.jar
  • commons-codec-1.9.jar
  • commons-logging-1.2.jar
  • fluent-hc-4.4.1.jar
  • httpclient-4.4.1.jar
  • httpcore-4.4.1.jar

This class is using JAX-RS annotation.

@Path(“/languageidentification”)
  defines the path that is mapped to the service URI
@GET
  defines the GET method handler
@Produces(MediaType.APPLICATION_JSON)
  defines the response type

The WebContent/WEB-INF/web.xml file contains the following servlet mapping:
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>

The username, password and baseURL for the Watson service are found in the credentials details of the bound service. You must bind a service to an app in order to generate the credentials for a service.

Leave a Reply

Your email address will not be published. Required fields are marked *