Wednesday, 3 May 2017

This week 9/2017 - The REST client API

There are a few implementation of REST client for Java. I will compare 3, I think, most popular implementations.
  1. Jersey (v. 2.25.x)
  2. Spring Web (v. 3.2.x)
  3. Apache CXF (v. 3.0.x)
My goal is to create component which can:
  1. Connect by secure channel - SSL
  2. Authentication bu Basic authorization mechanism.
  3. Send custom message.
  4. Read response and deserialize it into object.
So most common use of client. I was pointing to: flexible interface, clean code - nothing special. So I created following Java code


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import java.util.Arrays;
import java.util.Base64;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import org.apache.cxf.jaxrs.client.WebClient;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

public class App {

 // Apache CXF
 private static WebClient createWebClient() {
  return WebClient.create(getUrl(), "aa", "bbc", null);
 }
 private void testWebClient(){
  System.out.println("\n\ntestWebClient:");
//  System.out.println(createWebClient().path("todo22").accept(MediaType.TEXT_XML).get(Todo2.class));
  System.out.println(createWebClient().path("todo22").get(Todo2.class));
  System.out.println(createWebClient().path("todo22").get(String.class));
 }

 // Jersey
 private static Client createWebTarget() {
  HttpAuthenticationFeature authenticationFeature = HttpAuthenticationFeature.basic("aa", "bbc");
  return ClientBuilder.newBuilder().newClient().register(authenticationFeature);
 }

 private void testWebTarget(){
  WebTarget service = createWebTarget().target(getUrl());
  System.out.println("\n\ntestWebTarget :");
//  System.out.println(service.path("todo22").request(MediaType.TEXT_XML).get(Todo2.class));
  System.out.println(service.path("todo22").request().get(Todo2.class));
  System.out.println(service.path("todo22").request().get(String.class));
 }

 // Spring Web Rest
 private static HttpHeaders getHeaders(){
  String plainCredentials="aa:bbc";
  String base64Credentials = new String(Base64.getEncoder().encode(plainCredentials.getBytes()));

  HttpHeaders headers = new HttpHeaders();
  headers.add("Authorization", "Basic " + base64Credentials);
  headers.setAccept(Arrays.asList(org.springframework.http.MediaType.TEXT_XML));
  return headers;
 }

 private void testRestTemplate(){
  System.out.println("\n\ntestRestTemplate :");
  RestTemplate restTemplate = new RestTemplate();

  // restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
  restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
  HttpEntity<String> request = new HttpEntity<String>(getHeaders());
  System.out.println(restTemplate.exchange(getUrl() + "todo22", HttpMethod.GET, request, Todo2.class).getBody());
  System.out.println(restTemplate.exchange(getUrl() + "todo22", HttpMethod.GET, request, String.class).getBody());
 }

In my opinion the simplest interface has Apache CXF but you need to remember to create new instance for multiple services.
Jersey interface looks to be it most powerful. At the beginning there is created some service client template - core of client. Then every time when path method is executed there is created new instance of client with resource name.
Jersey support all kind of authentication methods providing tool. It is opposite to Spring Web RestTemplate where I had to prepare manually authorization header. Spring Web REST required much more code then two other solutions.

Resources:

No comments:

Post a Comment