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 instances manage client socket connections and are pretty heavy weight. Instances of this interface should be reused wherever possible, as it can be quite expensive to create and destroy these objects.
- 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.
The WebTarget interface represents a specific URI you want to invoke on.
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 ;
Eger ayni response objesi uzerinde bir den fazla kez readEntity metodunu kullanacaksak bu durumda bufferEntity metodunu kullanmamiz gereklidir.
If we didn’t buffer the entity, the second readEntity() call would result in an IllegalStateException.
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(); response.bufferEntity(); @SuppressWarnings("unchecked") List<String> resultList1 = response.readEntity(List.class); // If we didn’t buffer the entity, the second readEntity() call would result in // an IllegalStateException. String resultJSON = response.readEntity(String.class); // way-2 // Invoke HTTP GET method for the current request synchronously. List<String> resultList2 = builder.get(new GenericType<List<String>>() { }); System.out.println("### way1 ###"); System.out.println(resultList1); System.out.println(resultJSON); System.out.println("### way2 ###"); System.out.println(resultList2); client.close(); } }
Ornegimizi calistirdigimizda;
### way1 ### [Message-1, Message-2, Message-3] ["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
Leave a Reply