Vous êtes sur la page 1sur 6

GlassFish Jersey JAX-RS REST Service Client with Cookies and HTTP Proxy

Example

Abstract
Working with JAX-RS, I found most people tend to focus on the server side of things. But there
is a client side as well which doesn't involve JavaScript. I found it difficult finding client-side
examples which involved some more advanced, yet very common requirements, such as how to
use an HTTP proxy for your client and how to send cookies to the server. This article
consolidates my research into one example. As I bring in more requirements, I'll update this
example.

System Requirements
This example was developed and run using the following system setup. If
yours is different, it may work but no guarantees.

jdk1.8.0_65_x64

NetBeans 8.1 version 6.3

Maven 3.0.5 (Bundled with NetBeans)

Jersey 2.22.1 (From GlassFish)

The rest of the software dependencies can be found in this article.

Download
Git code example from GitHub

Maven
One of the first challenges is trying to determine which version of JAX-RS you're working with.
Jersey is the reference implementation of JAX-RS, and there are a lot of examples showing how
to do things with Jersey. But Jersey has gone through a lot of changes. Version 1.x is "Sun
Jersey" then version 2.x was completely repackaged as "GlassFish Jersey". As Jersey has
evolved, a lot of breaking changes have occurred, so examples may not work anymore.
This is my Maven dependency configuration for Jersey 2.22.1.

?
1
2
3
4
5
6
7
8
9
10
11
12

<dependencies>
<dependency>
<groupid>org.glassfish.jersey.core</groupid>
<artifactid>jersey-client</artifactid>
<version>2.22.1</version>
</dependency>
<dependency>
<groupid>org.glassfish.jersey.connectors</groupid>
<artifactid>jersey-apache-connector</artifactid>
<version>2.22.1</version>
</dependency>
</dependencies>

javax.ws.rs.client.Client
To create a JAX-RS client, the first thing you need is an instance of
javax.ws.rs.client.Client. Getting one of these is not as easy as you might think. I
probably ran across a half dozen different ways of getting a Client instance, so it's very
confusing. Listing 1 shows my ClientFactory. Let's take a look at it in more detail.
Listing1:ClientFactory
?
1 import javax.ws.rs.client.Client;
javax.ws.rs.client.ClientBuilder;
2 import
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
3 import org.glassfish.jersey.client.ClientConfig;
4 import org.glassfish.jersey.client.ClientProperties;
5
6 public class ClientFactory {
public static Client create()
7
{
8
System.out.printf("ClientFactory%n%n");
9
1
ClientConfig config = new ClientConfig();
0
{
config.property(ClientProperties.PROXY_URI,
11
"
http://localhost:7777
");
1
}
2
1
ApacheConnectorProvider provider = new ApacheConnectorProvider();
3
{
1
config.connectorProvider(new ApacheConnectorProvider());
4
}
1
Client client
5
= ClientBuilder.newClient(config);
1
6
return client;
1
}

7
1
8
1
9
2
0
2
1
2
2 }
2
3
2
4
2
5
2
6
2
7
Let's take a look at line 23 first. ClientBuilder.newClient(config) is a standard way
to create a Client object. Line 23 only uses classes from the JAX-RS API. The config
object however, created on line 12 is a Jersey-specific implementation of a JAX-RS interface.
Line 14 is where we set a property in the config object to specify the HTTP Proxy. This
configuration, however, doesn't do anything by itself because the default JAX-RS
implementation doesn't understand HTTP Proxies. This is why in the pom.xml we have a
dependency on jersey-apache-connector. This allows the defaults to be overridden
with Apache HttpClient. Lines 17-20 create an ApacheConnectorProvider and put it
in the config object. Without the ApacheConnectorProvider, the HTTP Proxy won't
be used. Now that we have a Client object, Let's see how to use it.

main(String [] args)
Getting a Client object was the first step. Now let's use the Client object to make a RESTful service call. The main() application in listing 2 does this.
Listing 2: A main(String [] args) application
?
1
2
3
4
5

import
import
import
import

javax.ws.rs.client.Client;
javax.ws.rs.client.WebTarget;
javax.ws.rs.core.MediaType;
javax.ws.rs.core.Response;

public class Main {

public static void main(String[] args) throws Exception {


6
Client client
7
= ClientFactory.create();
8
9
WebTarget target = client
1
.target("http://jsonplaceholder.typicode.com")
0
.path("posts/1")
;
11
1
Response response = target
2
.request(MediaType.TEXT_HTML)
1
.accept(MediaType.APPLICATION_JSON)
3
.header("User-Agent", "Java/1.8.0_65)
1
.cookie("name1","value1")
.cookie("name2","value2")
4
.get(Response.class)
1
;
5
1
System.out.printf("Response: %s%n%n", response);
6
System.out.printf("AllowdMethods: %s%n%n",
1 response.getAllowedMethods());
System.out.printf("Class: %s%n%n", response.getClass());
7
System.out.printf("Cookies: %s%n%n", response.getCookies());
1
System.out.printf("Date: %s%n%n", response.getDate());
8
System.out.printf("Entity: %s%n%n", response.getEntity());
1
System.out.printf("EntityTag: %s%n%n", response.getEntityTag());
9
System.out.printf("Headers: %s%n%n", response.getHeaders());
System.out.printf("Language: %s%n%n", response.getLanguage());
2
System.out.printf("LastModified: %s%n%n",
0
response.getLastModified());
2
System.out.printf("Length: %s%n%n", response.getLength());
1
System.out.printf("Links: %s%n%n", response.getLinks());
System.out.printf("Location: %s%n%n", response.getLocation());
2
System.out.printf("MediaType: %s%n%n", response.getMediaType());
2
System.out.printf("Metadata: %s%n%n", response.getMetadata());
2
System.out.printf("Status: %s%n%n", response.getStatus());
3
System.out.printf("StatusInfo: %s%n%n", response.getStatusInfo());
2
System.out.printf("StringHeaders: %s%n%n",
response.getStringHeaders());
4
System.out.printf("hasEntity: %b%n%n", response.hasEntity());
2
System.out.printf("readEntity(String): %s%n%n",
5 response.readEntity(String.class));
2
}
6 }
2
7
2
8
2
9
3
0
3

1
3
2
3
3
3
4
3
5
3
6
3
7
3
8
3
9
4
0
4
1
4
2
4
3
4
4
4
5
4
6
On lines 8-9 I use my custom ClientFactory to get a Client object. From the Client
object, the next step is to get a WebTarget. Lines 11-14 show this. The target() method
call is typically the base URL and the path() method call adds path information to the base.
The WebTarget is then used to make the call and get the response, and this can be done in
many different ways. In my example, I make the call and get the response on lines 16-23. First
it uses the request() method to configure what type of data the request is being sent to the
server, then the accept() method configures what type of data the server will be sending back
to the client. The header() method is then used to override the default value for "UserAgent". Proxies are usually sensitive to the "User-Agent" header and will reject requests
from JAX-RS clients using the default value. So change the "User-Agent" value to
something your proxy will accept. Next, the cookie() method calls add cookies to the
request. Finally the get(Response.class) method call makes an HTTP GET call to the
server and wraps the response from the server into a Response object. Fun!

The rest of the code is just logging what's in the Response object.
That's it, enjoy!

References
NGloom. (2015, May 15). How to add a http proxy for Jersey2 Client. stackoverflow.com.
Retrieved December 3, 2015 from http://stackoverflow.com/questions/18942648/how-to-add-ahttp-proxy-for-jersey2-client.
theotherian. (2013, August 11). setting up jersey client 2.0 to use httpclient, timeouts, and max
connections. theotherian.com. Retrieved December 3, 2015 from
http://www.theotherian.com/2013/08/jersey-client-2.0-httpclient-timeouts-max-connections.html.