How to create REST client in Java (1)

REST

This article describes how to send request to RESTful web service using Java.
I use Jersey version 1.x.

Introduction

For a while, I was trying to use REST API of Magnolia CMS in Java.
( I found some troubles, but finnaly resolved )

So I describe how to send REST request in Java.

This time, I explain how to send GET request. 

※Photo : IM FREE ( shackles by Wonderlane )

Environment

To send REST requests, I use Java, and Jersey (ver. 1.x)

Already Jersey became ver.2.x, but I use ver.1.x because I'm familiar to ver.1.x.

※Jersey is reference implementation of JAX-RS (Java API for RESTful Web Services )

If you use Java 1.7 or higher, Jersey 1.x, probably the following code works.

Java 1.7.0_55
Jersey 1.18.1

Get Jersey library

I'm using Apache Maven, so added the following dependency.

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.18.1</version>
        </dependency>

If you don't use Maven, get Jersey client library from Download page of Jersey.

Create REST client

Create REST client using Jersey.

At first, create a Java class for the following request processing (generrally used in RESTful Web Services).

HTTP MethodOperation
GETGet resource
PUTCreate resource
POSTUpdate resource
DELETEDelete resource

Create RestClient Class

At first, create client class.

I'll use this class to operate Magnoria, and REST API of magnolia needs Basic Authentication.
So I implement to support Basic Authentication.

* If you don't need Basic Authentication support, remove addfilter method.

Reference : REST API - Magnolia CMS

RestClient.java

package jp.co.agilegroup.rest;

import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientRequest;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * REST Client
 * @author masao.suda
 */
public class RestClient {

    private String account = null;
    private String password = null;
    
    public RestClient(String account, String password) {
        this.account = account;
        this.password = password;
    }
    
    private Client getClient() {
        Client client = new Client();
        client.addFilter(new HTTPBasicAuthFilter(account, password));
        return client;
    }
}

Implement GET Method

Next, implement GET Request processing.

GET Method is used for get Resources in RESTful Web Services.
A Resource is assigned unique one or more URI. We can get this resource by sending a GET request to these URI.

The most commonly used data type of resources is Text data such as HTML, XML, and JSON.

The following is the method to get Text data ( Please add this to the above RestClient class ).

RestClient.java - getString

    public String getString(String url, MediaType type) {
        Client client = getClient();
        WebResource resource = client.resource(url);
        ClientResponse response = resource.accept(type).get(ClientResponse.class);
        switch (response.getStatus()) {
        case 200 :  // OK
            break;
        default:
            return String.format("Code:%s Entity:%s",
                    response.getStatus(),
                    response.getEntity(String.class));
        }
        return response.getEntity(String.class);
    }

In the above method, I implement MediaType parameter.
This parameter value is set to Accept header of the HTTP request .
Several Web Services check value of Accept Header, and change data type of response. If you will use these type of services, I thinks parameterized method is convenient.

* For example, if value of Accept header is "application/xml" send "xml", if "application/json" send "json".

* Depends on Web Service's implementation.

It also has branches the processing by the HTTP status code.
Usually successful response code of GET request is 200(OK).
If error code is returned, it return the status code and contents of the HTML body.

Use RestClient

Use the above RestClient class and send GET request.

RestTest.java

package jp.co.agilegroup.rest;

import javax.ws.rs.core.MediaType;

public class RestTest {
    public static void main(String[] args) {
        RestClient client = new RestClient("admin", "admin");
        String uri = "http://....";    // specify a Request URI

        String xml = client.getString(uri, MediaType.APPLICATION_XML_TYPE);
        System.out.println(xml);
        
        String json = client.getString(uri, MediaType.APPLICATION_JSON_TYPE);
        System.out.println(json);
    }
}

The above code sends 2 requests, one sets "application/xml", the other sets "application/json" to Accept Header.
If Web service supports value of Accept Header, I can get XML and JSON formatted resources.

* In fact Jersey(server side), it can be implemented that returns the XML/JSON both of data depending on the value of the Accept header.

I sent GET request to the RESTful Web Serivce of Magnolia CMS, got the following responses.

URIhttp://localhost:8080/magnoliaAuthor/.rest/nodes/v1/website/demo-project
Resource(application/xml)<?xml version="1.0" encoding="UTF-8" standalone="yes"?><node><identifier>1be12547-ad82-4c83-8396-213466ceb003</identifie r><name>demo-project</name><nodes/><path>/demo-project</path><properties><property><multiple>false</multiple><name>logoI mg</name><type>String</type><values><value>jcr:a1918662-8cbe-4346-ac5a-1b24a9950e2b</value></values></property><property ><multiple>false</multiple><name>title</name><type>String</type><values><value>Home</value></values></property><property ><multiple>false</multiple><name>searchUUID</name><type>String</type><values><value>e301b5fc-275d-440a-8e98-17cba32c29c3 </value></values></property><property><multiple>false</multiple><name>hideInNav</name><type>Boolean</type><values><value >false</value></values></property><property><multiple>false</multiple><name>printLogoImg</name><type>String</type><value s><value>jcr:7240d7f5-4d10-4f56-a944-7864cfb77f5b</value></values></property><property><multiple>false</multiple><name>s iteTitle</name><type>String</type><values><value>Demo Project</value></values></property></properties><type>mgnl:page</t ype></node>
Resource(application/json){"name":"demo-project","type":"mgnl:page","path":"/demo-project","identifier":"1be12547-ad82-4c83-8396-213466ceb003","pr operties":[{"name":"logoImg","type":"String","multiple":false,"values":["jcr:a1918662-8cbe-4346-ac5a-1b24a9950e2b"]},{"n ame":"title","type":"String","multiple":false,"values":["Home"]},{"name":"searchUUID","type":"String","multiple":false," values":["e301b5fc-275d-440a-8e98-17cba32c29c3"]},{"name":"hideInNav","type":"Boolean","multiple":false,"values":["false "]},{"name":"printLogoImg","type":"String","multiple":false,"values":["jcr:7240d7f5-4d10-4f56-a944-7864cfb77f5b"]},{"nam e":"siteTitle","type":"String","multiple":false,"values":["Demo Project"]}],"nodes":[]}

Summary

This time, I described how to get Text data resources.
By using the client API of Jersey, is easily possible to get the XML or JSON formatted resources .

However, I'm not so happy that acquired data is treated as Text data.

Actually by using the client API of Jersey, it is possible to map the acquired data (XML and JSON) in Java objects .

Next time I will write about this method.