JAX RS – 28 – Client API – 01

Merhaba Arkadaslar
Bu bolumde JAX-RS Client API’yi incelemeye baslayacagiz.

  • javax.ws.rs.client.ClientBuilder
  • javax.ws.rs.client.Client
  • javax.ws.rs.client.WebTarget

ClientBuilder & Client

  • javax.ws.rs.client.Client interface/arabirimi JAX-RS Client API icin giris noktasidir.
The javax.ws.rs.client.Client interface is the main 
entry point into the JAX-RS Client API.
  • Client objeleri socket connection/baglantilarini yonetir/manage , bu nedenle heavy-weight objelerdir dolayisiyla Client objeleri mumkun mertebede tekrar kullanilmalidir (reused).
  • Client objeleri ClientBuilder abstract class’i yardimiyla olusturulur.

javax.ws.rs.client.ClientBuilder

package javax.ws.rs.client;

import java.net.URL;
import java.security.KeyStore;
import javax.ws.rs.core.Configurable;
import javax.ws.rs.core.Configuration;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;

public abstract class ClientBuilder implements Configurable {
public static Client newClient() {...}

public static Client newClient(final Configuration configuration) {...}

public static ClientBuilder newBuilder() {...}

	public abstract ClientBuilder sslContext(final SSLContext sslContext);

	public abstract ClientBuilder keyStore(final KeyStore keyStore, final char[] password);

	public ClientBuilder keyStore(final KeyStore keyStore, final String password) {
	}

	public abstract ClientBuilder trustStore(final KeyStore trustStore);

	public abstract ClientBuilder hostnameVerifier(final HostnameVerifier verifier);

	public abstract Client build();
}
  • ClientBuilder objesini ClientBuilder.newBuilder(); metodu ile olusturabiliriz.
  • Client objesini en kolay sekilde ClientBuilder.newClient(); metodu ile olusturabiliriz.
  • ClientBuilder sinifi/class Configurable arabirimini/interface uygulamaktadir (implements)


Client & WebTarget

  • Client objemizi ClientBuilder class’i yardimiyla olustururuz.
  • Client arabirimi/interface , Configurable arabirimini/interface kalitmaktadir (extends)

javax.ws.rs.client.Client

package javax.ws.rs.client;

import java.net.URI;

import javax.ws.rs.core.Configurable;
import javax.ws.rs.core.Link;
import javax.ws.rs.core.UriBuilder;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;

public interface Client extends Configurable<Client> {

    public void close();

    public WebTarget target(String uri);

    public WebTarget target(URI uri);

    public WebTarget target(UriBuilder uriBuilder);

    public WebTarget target(Link link);

    public Invocation.Builder invocation(Link link);

    public SSLContext getSslContext();


    public HostnameVerifier getHostnameVerifier();
}

  • Client objemiz yardimiyla WebTarget objemizi olustururuz.
  • WebTarget arabirimi/interface, belirttigimiz URI adresini cagirmamizi/invoke saglar.
    WebTarget objesi olusturmak icin target metodundan yararlaniriz , target metodunun overloaded versiyonlari yer almaktadir.
  • Bununla birlikte WebTarget ek metotlar icermektedir. Path ,matrix parameter , query parameter icin metotlar yer almaktadir.

javax.ws.rs.client.WebTarget

package javax.ws.rs.client;

import java.net.URI;
import java.util.Map;

import javax.ws.rs.core.Configurable;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;


public interface WebTarget extends Configurable<WebTarget> {


    public URI getUri();

    public UriBuilder getUriBuilder();

    public WebTarget path(String path);

    public WebTarget resolveTemplate(String name, Object value);
    //...
    public WebTarget matrixParam(String name, Object... values);

    public WebTarget queryParam(String name, Object... values);

    public Invocation.Builder request();

    public Invocation.Builder request(String... acceptedResponseTypes);

    public Invocation.Builder request(MediaType... acceptedResponseTypes);
}


Building Invoking Request

  • WebTarget objemizi olusturduktan sonra artik request metodu yardimiyla ilgili URI adresine istekte bulunabiliriz/cagirabiliriz/invoke
  • request() metodu geriye Invocation.Builder objesi donmektedir.

javax.ws.rs.client.WebTarget

package javax.ws.rs.client;

public interface WebTarget extends Configurable<WebTarget> {

    .....

    public Invocation.Builder request();

    public Invocation.Builder request(String... acceptedResponseTypes);

    public Invocation.Builder request(MediaType... acceptedResponseTypes);
}

  • Builder nested interface’i SyncInvoker arabirimini kalitmaktadir.

javax.ws.rs.client.Invocation

public interface Invocation {

    public static interface Builder extends SyncInvoker {


        public Invocation build(String method);

        public Invocation build(String method, Entity<?> entity);

        public Invocation buildGet();

        public Invocation buildDelete();

        public Invocation buildPost(Entity<?> entity);

        public Invocation buildPut(Entity<?> entity);

        public AsyncInvoker async();

        public Builder accept(String... mediaTypes);

        public Builder accept(MediaType... mediaTypes);

        public Builder acceptLanguage(Locale... locales);

        public Builder acceptLanguage(String... locales);

        public Builder acceptEncoding(String... encodings);

        public Builder cookie(Cookie cookie);

        public Builder cookie(String name, String value);

        public Builder cacheControl(CacheControl cacheControl);

        public Builder header(String name, Object value);
   
        public Builder headers(MultivaluedMap<String, Object> headers);
 
        public Builder property(String name, Object value);
    }


    public Invocation property(String name, Object value);

    public Response invoke();

    public <T> T invoke(Class<T> responseType);

    public <T> T invoke(GenericType<T> responseType);

    public Future<Response> submit();

    public <T> Future<T> submit(Class<T> responseType);

    public <T> Future<T> submit(GenericType<T> responseType);

    public <T> Future<T> submit(InvocationCallback<T> callback);
}

javax.ws.rs.client.SyncInvoker

public interface SyncInvoker {
    <T> T get(Class<T> responseType);
    <T> T get(GenericType<T> responseType);
    Response get();
    ...
}

Maven Dependency

Jersey icin herhangi bir dependency eklememize gerek yok.
RestEasy icin resteasy-client dependency eklememiz gereklidir.

pom.xml

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-client</artifactId>
    <version>${resteasy.version}</version>
</dependency>

Examples


MessageResource.java

package _22.client.api.service;

import java.util.Arrays;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/message-client-api")
public class MessageResource {

    @GET
    @Path("/message")
    public String getMessage() {
        String message = "Hello JAX-RS Client API!";
        return message;
    }

    @GET
    @Path("/messages")
    @Produces(MediaType.APPLICATION_JSON)
    public List<String> getMessages() {
        return Arrays.asList("Message-1", "Message-2", "Message-3");
    }
}

Simdi de ilgili URI adresler icin test kodlarimizi yazalim.

MessageClientAPITest1.java

package _22.client.api.test;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;

public class MessageClientAPITest1 {

	public static void main(String[] args) {

		String uri = "http://localhost:8080/injavawetrust.resteasy.tutorial/message-client-api/message";
		Client client = ClientBuilder.newClient();
		WebTarget target = client.target(uri);

		Invocation.Builder builder = target.request();
		String message = builder.get(String.class);
		System.out.println(message);

		client.close();
	}
}

Oncelikle ClientBuilder.newClient() metodu ile Client objemizi olusturalim.
Sonrasinda client.target metoduna URI bilgisini veriyoruz.
client.target(String uri) metodu geriye WebTarget donmektedir.

public WebTarget target(String uri);

Sonrasinda target.request() metodunu cagiriyoruz , geriye Invocation.Builder donmektedir.
builder ile HTTP GET isteginde bulunuyoruz. Burada response type olarak String.class bilgisini veriyoruz.

<T> T get(Class<T> responseType);

Sonrasinda test amacli String message bilgisini output’a yazdiriyoruz.

Hello JAX-RS Client API!

Bir diger ornek olarak diger metodumuzu calistiralim ;

MessageClientAPITest2.java

package _22.client.api.test;

import java.util.List;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.GenericType;

public class TestClientAPI2 {

	public static void main(String[] args) {

		String uri = "http://localhost:8080/injavawetrust.jersey.tutorial/message-client-api/messages";
		
                Client client = ClientBuilder.newClient();
		WebTarget target = client.target(uri);
		Invocation.Builder builder = target.request();

		List<String> resultList = builder.get(new GenericType<List<String>>() {});

		System.out.println(resultList);

		client.close();
	}
}

Burada getMessages metodumuz geriye List ve JSON formatinda donmektedir.
Jersey implementation icin burada GenericType‘i kullanabiliriz.

  <T> T get(GenericType<T> responseType);

Ornegimizi calistirdigimizda ;

[Message-1, Message-2, Message-3]

RestEasy icin 2 farkli yolla yapabiliriz ;

MessageClientAPITest2.java

package _22.client.api.test;

import java.util.List;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;

public class MessageClientAPITest2 {

   public static void main(String[] args) {

      String uri = "http://localhost:8080/injavawetrust.resteasy.tutorial/message-client-api/messages";

      Client client = ClientBuilder.newClient();
      WebTarget target = client.target(uri);

      Invocation.Builder builder = target.request();

      // way-1
      Response response = builder.get();
      
      @SuppressWarnings("unchecked")
      List<String> resultList1 = response.readEntity(List.class);

      // way-2
      List<String> resultList2 = builder.get(new GenericType<List<String>>() {});

      System.out.println("### way1 ###");
      System.out.println(resultList1);
      
      System.out.println("### way2 ###");
      System.out.println(resultList2);

      client.close();
   }
}

Ornegimizi calistirdigimizda;

### way1 ###
[Message-1, Message-2, Message-3]
### way2 ###
[Message-1, Message-2, Message-3]

Bir baska ornek olarak ;

LibraryResource.java

package _22.client.api.service;

import java.util.Arrays;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

import _22.client.api.model.Author;
import _22.client.api.model.Book;

@Path("/library-client-api")
public class LibraryResource {

	@GET
	@Path("/welcome")
	@Produces(MediaType.TEXT_PLAIN)
	public Response welcome() {
		String message = "Welcome Library!";
		ResponseBuilder builder = Response.ok(message);
		return builder.build();
	}

	@GET
	@Path("/book/{isbn}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getBookById(@PathParam("isbn") String isbn) {
		// assume that searched in DB.
		Book book = new Book(isbn, "Livro do desassossego", 550, 23.72);
		ResponseBuilder builder = Response.ok(book);
		return builder.build();
	}

	@GET
	@Path("/author")
	@Produces(MediaType.APPLICATION_XML)
	public Response getAuthor() {
		Author author = new Author("1", "Fernando", "Pessoa", "Portugal");
		ResponseBuilder builder = Response.ok(author);
		return builder.build();
	}

	@GET
	@Path("/authors")
	@Produces(MediaType.APPLICATION_XML)
	public List<Author> getAuthors() {
		Author author = new Author("1", "Turgut", "Uyar", "Turkey");
		Author author2 = new Author("2", "Albert", "Camus", "French");
		return Arrays.asList(author, author2);
	}
}

LibraryResource sinifimiz icin Client API methodlarimizi yazalim ;

LibraryClientAPITest1.java

package _22.client.api.test;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

public class LibraryClientAPITest1 {

	public static void main(String[] args) {

		String uri = "http://localhost:8080/injavawetrust.resteasy.tutorial/library-client-api/welcome";

		Client client = ClientBuilder.newClient();
		WebTarget target = client.target(uri);
		Invocation.Builder invocationBuilder = target.request();

		// way1
		Response response = invocationBuilder.get();
		String message = response.readEntity(String.class);

		System.out.println("### way1 ###");
		System.out.println("Response Status:" + response.getStatus());
		System.out.println(message);
		System.out.println();

		// way2
		String message2 = invocationBuilder.get(String.class);

		System.out.println("### way2 ###");
		System.out.println("Response Status:" + response.getStatus());
		System.out.println(message2);

		client.close();
	}
}


Ornegi calistirdigimizda;

### way1 ###
Response Status:200
Welcome Library!

### way2 ###
Response Status:200
Welcome Library!

Bir diger ornegimizde geri donus tipimiz @Produces(MediaType.APPLICATION_JSON)

Book.java

package _22.client.api.model;

public class Book {

	private String isbn;
	private String name;
	private int page;
	private double price;

	//constructors
	//getters and setters
	//toString

}

LibraryClientAPITest2.java

package _22.client.api.test;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;

import _22.client.api.model.Book;

public class LibraryClientAPITest2 {

	public static void main(String[] args) {

		// String uri = "http://localhost:8080/injavawetrust.resteasy.tutorial/library-client-api/book/100";
		String uri = "http://localhost:8080/injavawetrust.resteasy.tutorial/library-client-api/book/{id}";

		Client client = ClientBuilder.newClient();
		// WebTarget target = client.target(uri);
		WebTarget target = client.target(uri).resolveTemplate("id", "100");
		Invocation.Builder invocationBuilder = target.request();
		// The resolve Template() method fills in the id expression

		// way1
		Response response = invocationBuilder.get();
		Book book = response.readEntity(Book.class);

		// way2
		Response response2 = invocationBuilder.get();
		Book book2 = response2.readEntity(new GenericType<Book>() {
		});

		System.out.println("### way1 ###");
		System.out.println(response.getStatus());
		System.out.println(book);
		System.out.println();

		System.out.println("### way2 ###");
		System.out.println(response2.getStatus());
		System.out.println(book2);

		client.close();
	}
}

resolveTemplate metodu yardimiyla Path Param kullanabiliriz.

Ornegimizi calistirdigimizda ;

### way1 ###
200
Book [isbn=100, name=Livro do desassossego, page=550, price=23.72]

### way2 ###
200
Book [isbn=100, name=Livro do desassossego, page=550, price=23.72]

Bir baska ornek olarak donus tipi @Produces(MediaType.APPLICATION_XML) olan metodumuz icin test yazalim.

Author.java

package _22.client.api.model;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "author")
@XmlAccessorType(XmlAccessType.FIELD)
public class Author {

	@XmlElement
	private String id;
	@XmlElement
	private String name;
	@XmlElement
	private String surname;
	@XmlElement
	private String country;

	//constructors
	//getters and setters
	//toString

}

LibraryClientAPITest3.java

package _22.client.api.test;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import _22.client.api.model.Author;

public class LibraryClientAPITest3 {

	public static void main(String[] args) {

		String uri = "http://localhost:8080/injavawetrust.resteasy.tutorial/library-client-api/author";
		Client client = ClientBuilder.newClient();
		WebTarget target = client.target(uri);
		Invocation.Builder invocationBuilder = target.request();

		// way1
		Response response = invocationBuilder.get();
		Author author = response.readEntity(Author.class);

		// way2
		Response response2 = invocationBuilder.get();
		String xmlResponseString = response2.readEntity(String.class);

		System.out.println("### way1 ###");
		System.out.println(author);

		System.out.println("### way2 ###");
		System.out.println(xmlResponseString);

		client.close();
	}
}

Ornegimizi calistirdigimizda ;

### way1 ###
Author [id=1, name=Fernando, surname=Pessoa, country=Portugal]
### way2 ###
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<author><
	id>1</id>
	<name>Fernando</name>
	<surname>Pessoa</surname><
	country>Portugal</country>
</author>

Bir baska ornek olarak List<Author> donen metodumuzu test edelim.

### way1 ###
[Author [id=1, name=Turgut, surname=Uyar, country=Turkey], Author [id=2, name=Albert, surname=Camus, country=French]]
### way2 ###
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<authors>
	<author>
		<id>1</id>
		<name>Turgut</name>
		<surname>Uyar</surname>
		<country>Turkey</country>
	</author><
	author>
		<id>2</id>
		<name>Albert</name>
		<surname>Camus</surname><
		country>French</country>
	</author><
</authors>

LibraryClientAPITest4.java

package _22.client.api.test;

import java.util.List;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;

import _22.client.api.model.Author;

public class LibraryClientAPITest4 {

	public static void main(String[] args) {

		String uri = "http://localhost:8080/injavawetrust.jersey.tutorial/library-client-api/authors";
		Client client = ClientBuilder.newClient();
		WebTarget target = client.target(uri);
		Invocation.Builder invocationBuilder = target.request();

		// way1
		Response response = invocationBuilder.get();
		List<Author> authorList = response.readEntity(new GenericType<List<Author>>() {});

		// way2
		Response response2 = invocationBuilder.get();
		String xmlResponseString = response2.readEntity(String.class);

		System.out.println("### way1 ###");
		System.out.println(authorList);
		
		System.out.println("### way2 ###");
		System.out.println(xmlResponseString);

		client.close();
	}
}

Ornegimizi calistirdigimizda;

### way1 ###
[Author [id=1, name=Turgut, surname=Uyar, country=Turkey], Author [id=2, name=Albert, surname=Camus, country=French]]
### way2 ###

<?xml version="1.0" encoding="UTF-8"?>
<authors>
   <author>
      <id>1</id>
      <name>Turgut</name>
      <surname>Uyar</surname>
      <country>Turkey</country>
   </author>
   <author>
      <id>2</id>
      <name>Albert</name>
      <surname>Camus</surname>
      <country>French</country>
   </author>
</authors>

Github kaynak kodlar / source folder
injavawetrust.resteasy
injavawetrust.jersey

Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer

Print Friendly, PDF & Email

Leave a Reply

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