3 Developing RESTful Web Service Clients

This chapter describes how to develop WebLogic Web service clients that conform to the Representational State Transfer (REST) architectural style using Java API for RESTful Web Services (JAX-RS).

This chapter includes the following sections:

For information about developing RESTful Web service clients using Oracle JDeveloper, see "Creating RESTful Web Services and Clients" in Developing Applications with Oracle JDeveloper.

About RESTful Web Service Client Development

The Jersey JAX-RS RI provides a client API for developing RESTful Web services clients. To access the client API, you create an instance of the weblogic.jaxrs.api.client.Client class and then use that instance to access the Web resource and send HTTP requests.

Note:

A standard client API will be supported as part of the JSR-311 JAX-RS 2.0 specification.

The following sections provide more information about RESTful Web service client development:

Summary of Tasks to Develop RESTful Web Service Clients

The following table summarizes a subset of the tasks that are required to develop RESTful Web service clients. For more information about advanced tasks, see More Advanced RESTful Web Service Client Tasks.

Table 3-1 Summary of Tasks to Develop RESTful Web Service Clients

Task More Information

Create an instance of the weblogic.jaxrs.api.client.Client class.

Creating and Configuring a Client Instance

Create an instance of the Web resource.

Creating a Web Resource Instance

Send requests to the resource. For example, HTTP requests to GET, PUT, POST, and DELETE resource information.

Sending Requests to the Resource

Receive responses from the resource.

Receiving a Response from a Resource


Example of a RESTful Web Service Client

The following provides a simple example of a RESTful Web service client that can be used to call the RESTful Web service defined in Example 2-1, "Simple RESTful Web Service". In this example:

Additional examples are listed in Learn More About RESTful Web Services.

Example 3-1 Simple RESTful Web Service Client

package samples.helloworld.client;
 
import weblogic.jaxrs.api.client.Client;
import com.sun.jersey.api.client.WebResource;
 
public class helloWorldClient {
    public helloWorldClient() {
        super();
    }
 
    public static void main(String[] args) {
        Client c = Client.create();
        WebResource resource = c.resource("http://localhost:7101/RESTfulService-Project1-context-root/jersey/helloWorld");
        String response = resource.get(String.class);
    }
}

Creating and Configuring a Client Instance

To access the Jersey JAX-RS RI client API, create an instance of the weblogic.jaxrs.api.client.Client class.

Note:

Alternatively, you can create an instance of the com.sun.jersey.api.client.Client class. However, you will not be able to take advantage of the Oracle extensions, such as securing the RESTful client using Oracle Web Services Manager (OWSM) policies, as described in Securing RESTful Web Services and Clients Using OWSM Policies.

Optionally, you can pass client configuration properties, defined in Table 3-2, when creating the client instance by defining a com.sun.jersey.api.client.config.ClientConfig and passing the information to the create method. For more information, see https://jersey.java.net/apidocs/1.13/jersey/index.html?com/sun/jersey/api/client/config/ClientConfig.html.

Table 3-2 RESTful Web Service Client Configuration Properties

Property Description

PROPERTY_BUFFER_RESPONSE_ENTITY_ON_EXCEPTION

Boolean value that specifies whether the client should buffer the response entity, if any, and close resources when a UniformInterfaceException is thrown. This property defaults to true.

PROPERTY_CHUNKED_ENCODING_SIZE

Integer value that specifies the chunked encoding size. A value equal to or less than 0 specifies that the default chunk size should be used. If not set, then chunking will not be used.

PROPERTY_CONNECT_TIMEOUT

Integer value that specifies the connect timeout interval in milliseconds. If the property is 0 or not set, then the interval is set to infinity.

PROPERTY_FOLLOW_REDIRECTS

Boolean value that specifies whether the URL will redirect automatically to the URI declared in 3xx responses. This property defaults to true.

PROPERTY_READ_TIMEOUT

Integer value that specifies the read timeout interval in milliseconds. If the property is 0 or not set, then the interval is set to infinity.


Example 3-2 provides an example of how to create a client instance.

Example 3-2 Creating a Client Instance

import weblogic.jaxrs.api.client.Client;
...
    public static void main(String[] args) {
        Client c = Client.create();
...

Example 3-3 provides an example of how to create a client instance and pass configuration properties to the create method.

Example 3-3 Creating and Configuring a Client Instance

import com.sun.jersey.api.client.*;
import weblogic.jaxrs.api.client.Client;
...
    public static void main(String[] args) {
        ClientConfig cc = new DefaultClientConfig();
        cc.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
        Client c = Client.create(cc);
...

Alternatively, you can configure a client instance after the client has been created, by setting properties on the map returned from the getProperties method or calling a specific setter method.

Example 3-4 provides an example of how to configure a client after it has been created. In this example:

  • PROPERTY_FOLLOW_REDIRECTS is configured by setting the property on the map returned from the getProperties method.

  • PROPERTY_CONNECT_TIMEOUT is configured using the setter method.

Example 3-4 Configuring a Client Instance After It Has Been Created

import com.sun.jersey.api.client.*;
import weblogic.jaxrs.api.client.Client;
...
    public static void main(String[] args) {
        Client c = Client.create();
        c.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
        c.setConnectTimeout(3000);
...

Example 3-5 provides an example of how to configure a client instance to use basic authentication.

Example 3-5 Configuring a Client Instance to Use Basic Authentication

import javax.ws.rs.core.MediaType;
 
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
...
      Client c = Client.create();
      c.addFilter(new HTTPBasicAuthFilter("weblogic", "weblogic1"));
      WebResource resource = c.resource("http://localhost:7001/management/tenant-monitoring/datasources/JDBC%20Data%20Source-0");
      String response = resource.accept("application/json").get(String.class); //application/xml
      // resource.accept(MediaType.APPLICATION_JSON_TYPE).get(String.class);
      System.out.println(response);
...

Creating a Web Resource Instance

Before you can issue requests to a RESTful Web service, you must create an instance of com.sun.jersey.api.client.WebResource or com.sun.jersey.api.client.AsyncWebResource to access the resource specified by the URI. The WebResource or AsyncWebResource instance inherits the configuration defined for the client instance. For more information, see:

Note:

Because clients instances are expensive resources, if you are creating multiple Web resources, it is recommended that you re-use a single client instance whenever possible.

Example 3-6 provides an example of how to create an instance to a Web resource hosted at http://example.com/helloworld.

Example 3-6 Creating a Web Resource Instance

import com.sun.jersey.api.client.*;
import weblogic.jaxrs.api.client.Client;
...
    public static void main(String[] args) {\
...
        Client c = Client.create();
        WebResource resource = c.resource("http://example.com/helloWorld");
...

Example 3-6 provides an example of how to create an instance to an asynchronous Web resource hosted at http://example.com/helloworld.

Example 3-7 Creating an Asynchronous Web Resource Instance

import com.sun.jersey.api.client.*;
import weblogic.jaxrs.api.client.Client;
...
    public static void main(String[] args) {\
...
        Client c = Client.create();
         AsyncWebResource asyncResource = c.resource("http://example.com/helloWorld");
...

Sending Requests to the Resource

Use the WebResource or AsyncWebResource instance to build requests to the associated Web resource, as described in the following sections:

How to Build Requests

Requests to a Web resource are structured using the builder pattern, as defined by the com.sun.jersey.api.client.RequestBuilder interface. The RequestBuilder interface is implemented by com.sun.jersey.api.client.WebResource, com.sun.jersey.api.client.AsyncWebResource, and other resource classes.

You can build a request using the methods defined in Table 3-3, followed by the HTTP request method, as described in How to Send HTTP Requests. Examples of how to build a request are provided in the sections that follow.

For more information about RequestBuilder and its methods, see https://jersey.java.net/apidocs/1.13/jersey/index.html?com/sun/jersey/api/client/RequestBuilder.html.

Table 3-3 Building a Request

Method Description

accept()

Defines the acceptable media types. See How to Configure the Accept Header.

acceptLanguage()

Defines the acceptable languages using the acceptLanguage method.

cookie()

Adds a cookie to be set.

entity()

Configures the request entity. See How to Configure the Request Entity.

header()

Adds an HTTP header and value. See How to Configure the Accept Header.

type()

Configures the media type. See How to Configure the Request Entity.


How to Send HTTP Requests

Table 3-4 list the WebResource and AsyncWebResource methods that can be used to send HTTP requests.

In the case of AsyncWebResource, a java.util.concurrent.Future<V> object is returned, which can be used to access the result of the computation later, without blocking execution. For more information about Future<V>, see http://docs.oracle.com/javase/7/docs/api/index.html?java/util/concurrent/Future.html.

Table 3-4 WebResource Methods to Send HTTP Requests

Method Description

get()

Invoke the HTTP GET method to get a representation of the resource.

post()

Invoke the HTTP POST method to create or update the representation of the specified resource.

put()

Invoke the HTTP PUT method to update the representation of the resource.

delete()

Invoke the HTTP DELETE method to delete the representation of the resource.


If the response has an entity (or representation), then the Java type of the instance required is declared in the HTTP method.

Example 3-8 provides an example of how to send an HTTP GET request. In this example, the response entity is requested to be an instance of String. The response entity will be de-serialized to a String instance.

Example 3-8 Sending an HTTP GET Request

import com.sun.jersey.api.client.WebResource;
...
    public static void main(String[] args) {
...
         WebResource resource = c.resource("http://example.com/helloWorld");
         String response = resource.get(String.class);
...

Example 3-9 provides an example of how to send an HTTP PUT request and put the entity foo:bar into the Web resource. In this example, the response entity is requested to be an instance of com.sun.jersey.api.client.ClientResponse.

Example 3-9 Sending an HTTP PUT Request

import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.ClientResponse;
...
    public static void main(String[] args) {
...
         WebResource resource = c.resource("http://example.com/helloWorld");
         ClientResponse response = resource.put(ClientResponse.class, "foo:bar");
...

If you wish to send an HTTP request using a generic type, to avoid type erasure at runtime, you need to create a com.sun.jersey.api.client.GenericType object to preserve the generic type. For more information, see https://jersey.java.net/apidocs/1.13/jersey/index.html?com/sun/jersey/api/client/GenericType.html.

Example 3-10 provides an example of how to send an HTTP request using a generic type using GenericType to preserve the generic type.

Example 3-10 Sending an HTTP GET Request Using a Generic Type

import com.sun.jersey.api.client.WebResource;
...
    public static void main(String[] args) {
...
        WebResource resource = c.resource("http://example.com/helloWorld");
        List<String> list = resource.get(new GenericType<List<String>>() {});
...

How to Pass Query Parameters

You can pass query parameters in the GET request by defining a javax.ws.rs.core.MultivaluedMap and using the queryParams method on the Web resource to pass the map as part of the HTTP request.

For more information about MultivaluedMap, see http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/core/MultivaluedMap.html.

Example 3-11 provides an example of how to pass parameters in a GET request to a Web resource hosted at http://example.com/helloworld, resulting in the following request URI: http://example.com/base?param1=val1&param2=val2

Example 3-11 Passing Query Parameters

import com.sun.jersey.api.client.WebResource;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.MultivaluedMapImpl;
...
    public static void main(String[] args) {
...
        WebResource resource = c.resource("http://example.com/helloWorld");
        MultivaluedMap queryParams = new MultivaluedMapImpl();
        queryParams.add("param1", "val1");
        queryParams.add("param2", "val2");
        String response = resource.queryParams(queryParams).get(String.class);
...

How to Configure the Accept Header

Configure the Accept header for the request using the accept method on the Web resource.

Example 3-12 provides an example of how to specify text/plain as the acceptable MIME media type in a GET request to a Web resource hosted at http://example.com/helloworld.

Example 3-12 Configuring the Accept Header

import com.sun.jersey.api.client.WebResource;
...
    public static void main(String[] args) {
...
        WebResource resource = c.resource("http://example.com/helloWorld");
        String response = resource.accept("text/plain").get(String.class);
...

How to Add a Custom Header

Add a custom header to the request using the header method on the Web resource.

Example 3-13 provides an example of how to add a custom header FOO with the value BAR in a GET request to a Web resource hosted at http://example.com/helloworld.

Example 3-13 Adding a Custom Header

import com.sun.jersey.api.client.WebResource;
...
    public static void main(String[] args) {
...
        WebResource resource = c.resource("http://example.com/helloWorld");
        String response = resource.header("FOO", "BAR").get(String.class);
...

How to Configure the Request Entity

Configure the request entity and type using the entity method on the Web resource. Alternatively, you can configure the request entity type only using the type method on the Web resource.

Example 3-14 provides an example of how to configure a request entity and type.

Example 3-14 Configuring the Request Entity

import com.sun.jersey.api.client.WebResource;
...
    public static void main(String[] args) {
...
        WebResource resource = c.resource("http://example.com/helloWorld");
        String response = resource.entity(request, MediaType.TEXT_PLAIN_TYPE).get(String.class);
...

Example 3-15 provides an example of how to configure the request entity media type only.

Example 3-15 Configuring the Request Entity Media Type Only

import com.sun.jersey.api.client.WebResource;
...
    public static void main(String[] args) {
...
        WebResource resource = c.resource("http://example.com/helloWorld");
        String response = resource.type(MediaType.TEXT_PLAIN_TYPE).get(String.class);
...

Receiving a Response from a Resource

You define the Java type of the entity (or representation) in the response when you call the HTTP method, as described in How to Send HTTP Requests.

If response metadata is required, declare the Java type com.sun.jersey.api.client.ClientResponse as the response type. the ClientResponse type enables you to access status, headers, and entity information.

The following sections describes the response metadata that you can access using the ClientResponse. For more information about ClientResponse, see https://jersey.java.net/apidocs/1.13/jersey/index.html?com/sun/jersey/api/client/ClientResponse.html.

How to Access the Status of Request

Access the status of a client response using the getStatus method on the ClientResponse object. For a list of valid status codes, see https://jersey.java.net/apidocs/1.13/jersey/index.html?com/sun/jersey/api/client/ClientResponse.Status.html.

Example 3-12 provides an example of how to access the status code of the response.

Example 3-16 Accessing the Status of the Request

import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.ClientResponse;
...
    public static void main(String[] args) {
...
        WebResource resource = c.resource("http://example.com/helloWorld");
        ClientResponse response = resource.get(ClientResponse.class);
        int status = response.getStatus();
...

How to Get the Response Entity

Get the response entity using the getEntity method on the ClientResponse object.

Example 3-12 provides an example of how to get the response entity.

Example 3-17 Getting the Response Entity

import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.ClientResponse;
...
    public static void main(String[] args) {
...
        WebResource resource = c.resource("http://example.com/helloWorld");
        ClientResponse response = resource.get(ClientResponse.class);
        String entity = response.getEntity(String.class);
...

More Advanced RESTful Web Service Client Tasks

For more information about advanced RESTful Web service client tasks, including those listed below, see the Jersey 1.13 User Guide at https://jersey.java.net/nonav/documentation/1.13/user-guide.html.

  • Adding new representation types

  • Using filters

  • Enabling security with HTTP(s) URLConnection

Invoking a RESTful Web Service from a Standalone Client

When invoking a RESTful Web service from an environment that does not have Oracle Fusion Middleware or WebLogic Server installed locally, with the entire set of Oracle Fusion Middleware or WebLogic Server classes in the CLASSPATH, you can use the standalone client JAR file when invoking the Web service.

The standalone client JAR supports basic JAX-RS client-side functionality and OWSM security policies.

To use the standalone client JAR file with your client application, perform the following steps:

  1. Create a Java SE client using your favorite IDE, such as Oracle JDeveloper. For more information, see "Developing and Securing Web Services and Clients" in Developing Applications with Oracle JDeveloper.

  2. Copy the file ORACLE_HOME/oracle_common/modules/clients/com.oracle.jersey.fmw.client_12.1.2.jar from the computer hosting Oracle Fusion Middleware to the client computer, where ORACLE_HOME is the directory you specified as Oracle Home when you installed Oracle Fusion Middleware.

    For example, you might copy the file into the directory that contains other classes used by your client application.

  3. Add the JAR file to your CLASSPATH.

    Note:

    Ensure that your CLASSPATH includes the JAR file that contains the Ant classes (ant.jar) as a subset are used by the standalone client JAR files. This JAR file is typically located in the lib directory of the Ant distribution.

  4. Configure your environment for Oracle Web Services Manager (OWSM) policies. This step is optional, required only if you are attaching OWSM security policies to the RESTful client.

    The configuration steps required vary based on the type of policy being attached. Examples are provided below. For additional configuration requirements, see "Configuring Java SE Applications to Use OPSS" in Securing Applications with Oracle Platform Security Services.

    Note:

    To access the Jersey JAX-RS RI client API, ensure that you create an instance of the weblogic.jaxrs.api.client.Client class.

    Alternatively, you can create an instance of the com.sun.jersey.api.client.Client class. However, you will not be able to take advantage of the Oracle extensions, such as securing the RESTful client using Oracle Web Services Manager (OWSM) policies, as described in Securing RESTful Web Services and Clients Using OWSM Policies.

    Example: Basic Authentication

    For example, to support basic authentication using the oracle/wss_http_token_client_policy security policy, perform the following steps:

    1. Copy the jps-config-jse.xml and audit-store.xml files from the domain_home/config/fmwconfig directory, where domain_home is the name and location of the domain, to a location that is accessible to the RESTful client.

    2. Create a wallet (cwallet.sso) in the same location that you copied the files in step 2 that defines a map called oracle.wsm.security and the credential key name that the client application will use (for example, weblogic-csf-key).

      The location of the file cwallet.sso is specified in the configuration file jps-config-jse.xml with the element <serviceInstance>.For more information, see "Using a Wallet-based Credential Store" in Securing Applications with Oracle Platform Security Services.

    3. On the Java command line, pass the following property defining the JPS configuration file copied in step 1:

      -Doracle.security.jps.config=<pathToConfigFile>
      

      For more information, see "Scenario 3: Securing a Java SE Application" in Securing Applications with Oracle Platform Security Services.

    Example: SSL

    For example, to support SSL policies, perform the following steps:

    1. Copy the jps-config-jse.xml and audit-store.xml files from the domain_home/config/fmwconfig directory, where domain_home is the name and location of the domain, to a location that is accessible to the RESTful client.

    2. On the Java command line, pass the following properties:defining the JPS configuration file copied in step 1:

      Define the JPS configuration file copied in step 1:

      -Doracle.security.jps.config=<pathToConfigFile>
      

      For more information, see "Scenario 3: Securing a Java SE Application" in Securing Applications with Oracle Platform Security Services.

      Define the trust store containing the trusted certificates:

      -Djavax.net.ssl.trustStore=<trustStore>
      

      For more information, see "Setting Up the WebLogic Server in Case of a Java SE Application" in "Setting Up a One-Way SSL Connection to the LDAP" in Securing Applications with Oracle Platform Security Services.

      Define the trust store password:

      -Djavax.net.ssl.trustStorePassword=<password>