`
rogerhunt
  • 浏览: 60849 次
  • 性别: Icon_minigender_1
  • 来自: 新加坡
社区版块
存档分类
最新评论

RESTful客户端的一种java实现

阅读更多
RESTful client implemented by java

RESTful客户端的一种java实现


Apache HttpClient
The Apache foundation has written a nice, extendible, HTTP client library called
HttpClient.* It is currently on version 4.0 as of the writing of this book. Although it is
not JAX-RS-aware, it does have facilities for preemptive authentication and APIs for
dealing with a few different media types like forms and multipart. Some of its other
features are a full interceptor model, automatic cookie handling between requests, and
pluggable authentication to name a few. Let’s look at a simple example:
import org.apache.http.*;
import org.apache.http.client.*;
public class MyClient {
public static void main(String[] args) throws Exception {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet("http://example.com/customers/1");
get.addHeader("accept", "application/xml");
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeExceptioin("Operation failed: " +
response.getStatusLine().getStatusCode());
}
System.out.println("Content-Type: " +
response.getEntity().getContentType().getValue());
BufferedReader reader = new BufferedReader(new
InputStreamReader(response.getEntity()
.getInputStream()));
String line = reader.readLine();
while (line != null) {
* For more information, see http://hc.apache.org.
170 | Chapter 13: RESTful Java Clients
Download at WoweBook.Com
System.out.println(line);
line = reader.readLine();
}
client.getConnectionManager().shutdown();
}
}

In Apache HttpClient 4.x, the org.apache.http.client.DefaultHttpClient class is responsible
for managing HTTP connections. It handles the default authentication settings,
pools and manages persistent HTTP connections (keepalive), and any other
default configuration settings. It is also responsible for executing requests. The
org.apache.http.client.methods.HttpGet class is used to build an actual HTTP GET
request. You initialize it with a URL and set any request headers you want using the
HttpGet.addHeader() method. There are similar classes in this package for doing POST,
PUT, and DELETE invocations. Once you have built your request, you execute it by
calling DefaultHttpClient.execute(), passing in the request you built. This returns an
org.apache.http.HttpResponse object. To get the response code from this object, execute
HttpResponse.getStatusLine().getStatusCode(). The HttpResponse.getEntity()
method returns an org.apache.http.HttpEntity object, which represents the message
body of the response. From it you can get the Content-Type by executing
HttpEntity.getContentType() as well as a java.io.InputStream so you can read the response.
When you are done invoking requests, you clean up your connections by calling
HttpClient.getConnectionManager().shutdown().
To push data to the server via a POST or PUT operation, you need to encapsulate your
data within an instance of the org.apache.http.HttpEntity interface. The framework
has some simple prebuilt ones for sending strings, forms, byte arrays, and input streams.
Let’s look at sending some XML.
In this example, we want to create a customer in a RESTful customer database. The
API works by POSTing an XML representation of the new customer to a specific URI.
A successful response is 201, “Created.” Also, a Location response header is returned
that points to the newly created customer:
import org.apache.http.*;
import org.apache.http.client.*;
public class MyClient {
public static void main(String[] args) throws Exception {
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://example.com/customers");
StringEntity entity = new StringEntity("<customer id='333'/>");
entity.setContentType("application/xml");
post.setEntity(entity);
HttpClientParams.setRedirection(post.getParams(), false);
HttpResponse response = client.execute(post);
if (response.getStatusLine().getStatusCode() != 201) {
throw new RuntimeExceptioin("Operation failed: " +
response.getStatusLine().getStatusCode());
Apache HttpClient | 171
Download at WoweBook.Com
}
String location = response.getLastHeader("Location")
.getValue();
System.out.println("Object created at: " + location);
System.out.println("Content-Type: " +
response.getEntity().getContentType().getValue());
BufferedReader reader = new BufferedReader(new
InputStreamReader(response.getEntity().getContent()));
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
client.getConnectionManager().shutdown();
}
}

We create an org.apache.http.entity.StringEntity to encapsulate the XML we want
to send across the wire. We set its Content-Type by calling StringEntity.setContent
Type(). We add the entity to the request by calling HttpPost.setEntity(). Since we are
expecting a redirection header with our response and we do not want to be automatically
redirected, we must configure the request to not do automatic redirects. We do
this by calling HttpClientParams.setRedirection(). We execute the request the same
way we did with our GET example. We get the Location header by calling
HttpResponse.getLastHeader().
Authentication
The Apache HttpClient 4.x supports Basic, Digest, and Client Certificate authentication.
Basic and Digest authentication are done through the DefaultHttpClient.getCre
dentialsProvider().setCredentials() method. Here’s an example:
DefaultHttpClient client = new DefaultHttpClient();
client.getCredentialsProvider().setCredentials(
new AuthScope("example.com", 443),
new UsernamePasswordCredentials("bill", "geheim");
);
The org.apache.http.auth.AuthScope class defines the server and port that you want
to associate with a username and password. The org.apache.http.auth.UsernamePass
wordCredentials class encapsulates the username and password into an object. You can
call setCredentials() for every domain you need to communicate with securely.
Apache HttpClient, by default, does not do preemptive authentication for the Basic
and Digest protocols, but does support it. Since the code to do this is a bit verbose, we
won’t cover it in this book.
172 | Chapter 13: RESTful Java Clients
Download at WoweBook.Com
Client Certificate authentication
Apache HttpClient also supports Client Certificate authentication. As with HttpsURL
Connection, you have to load in a KeyStore that contains your client certificates.
“java.net.URL” on page 165 describes how to do this. You initialize an
org.apache.http.conn.ssl.SSLSocketFactory with a loaded KeyStore and associate it
with the DefaultHttpClient. Here is an example of doing this:
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import org.apache.http.*;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.*;
import org.apache.http.conn.scheme.*;
import org.apache.http.conn.ssl.*;
import org.apache.http.impl.client.DefaultHttpClient;
public class MyClient {
public final static void main(String[] args) throws Exception {
DefaultHttpClient client = new DefaultHttpClient();
KeyStore trustStore = KeyStore.getInstance(
KeyStore.getDefaultType());
FileInputStream instream = new FileInputStream(
new File("my.keystore"));
try {
trustStore.load(instream, "changeit".toCharArray());
} finally {
instream.close();
}
SSLSocketFactory socketFactory =
new SSLSocketFactory(trustStore);
Scheme scheme = new Scheme("https", socketFactory, 443);
client.getConnectionManager()
.getSchemeRegistry().register(scheme);
HttpGet httpget = new HttpGet("https://localhost/");
... proceed with the invocation ...
}
}

Advantages and Disadvantages
Apache HttpClient is a more complete solution and is better designed than
java.net.HttpURLConnection. Although you have to download it separately from the
JDK, I highly recommend you take a look at it. It has none of the disadvantages of
HttpURLConnection, except that it is not JAX-RS-aware.
Apache HttpClient | 173
Download at WoweBook.Com
RESTEasy Client Framework
RESTEasy† is the JBoss (Red Hat) JAX-RS implementation. As with java.net.HttpURL
Connection and Apache HTTP Client, it provides a programmatic API to submit HTTP
requests with the additional feature of it being JAX-RS-aware. To use the API, you
create org.jboss.resteasy.client.ClientRequest objects. You build up the request using
the following constructor and methods:
public class ClientRequest {
public ClientRequest(String uriTemplate) {}
public ClientRequest followRedirects(boolean follow) {}
public ClientRequest accept(String accept) {}
public ClientRequest formParameter(String parameterName,
Object value) {}
public ClientRequest queryParameter(String parameterName,
Object value) {}
public ClientRequest matrixParameter(String parameterName,
Object value) {}
public ClientRequest header(String headerName, Object value) {}
public ClientRequest cookie(String cookieName, Object value) {}
public ClientRequest cookie(Cookie cookie) {}
public ClientRequest pathParameter(String parameterName,
Object value)
public ClientRequest body(String contentType, Object data) {}
...
}

The ClientRequest constructor can take any expression you put in an @Path annotation,
but it must also have scheme, host, and port information. Here’s an example of building
up a GET request:
ClientRequest request =
new ClientRequest("http://example.com/customers/{id}");
request.accept("application/xml")
.pathParameter("id", 333);
We allocate the ClientRequest instance, passing in a URL template. We set the
Accept header to state we want XML returned and the id path parameter to 333. To
invoke the request, call one of ClientRequest’s HTTP invocation methods listed here:
public class ClientRequest {
...
// HTTP METHODS
public <T> T getTarget(Class<T> returnType) throws Exception {}
public <T> ClientResponse<T> get(Class<T> returnType)
throws Exception {}
public ClientResponse put() throws Exception {}
public <T> ClientResponse<T> put(Class<T> returnType)
throws Exception {}
† For more information, see http://jboss.org/resteasy.
174 | Chapter 13: RESTful Java Clients
Download at WoweBook.Com
public ClientResponse post() throws Exception {}
public <T> ClientResponse<T> post(Class<T> returnType)
throws Exception {}
public <T> T postTarget(Class<T> returnType) throws Exception {}
public ClientResponse delete() throws Exception {}
public <T> ClientResponse<T> delete(Class<T> returnType)
throws Exception {}
...
}

Finishing up our GET request example, we invoke either the get() or getTarget()
methods. The getTarget() method invokes the request and automatically converts it
to the type you want returned. For example:
ClientRequest request =
new ClientRequest("http://example.com/customers/{id}");
request.accept("application/xml")
.pathParameter("id", 333);
Customer customer = request.getTarget(Customer.class);
In this example, our Customer class is a JAXB annotated class. When ClientRequest.get
Target() is invoked, the request object builds the URL to invoke on using the passed
in path parameter, sets the Accept header with the desired media type, and then calls
the server. If a successful response comes back, the client framework matches the
Customer class with an appropriate MessageBodyReader and unmarshalls the returned
XML into a Customer instance. If an unsuccessful response comes back from the server,
the framework throws an org.jboss.resteasy.client.ClientResponseFailure instead
of returning a Customer object:
public class ClientResponseFailure extends RuntimeException {
...
public ClientResponse<byte[]> getResponse() {}
}
If you need to get the response code or want to look at a response header from your
HTTP invocation, you can opt to invoke the ClientRequest.get() method instead. This
method returns an org.jboss.resteasy.client.ClientResponse object instead of the
unmarshalled requested type. Here’s what ClientResponse looks like:
public abstract class ClientResponse<T> extends Response {
public abstract MultivaluedMap<String, String> getHeaders();
public abstract Response.Status getResponseStatus();
public abstract T getEntity();
...
public abstract void releaseConnection();
}

The ClientResponse class extends the javax.ws.rs.core.Response class. You can obtain
the status code by calling ClientResponse.getStatus() or getResponseStatus() if you
want an enum. The getEntity() method unmarshalls the HTTP message body into the
type you want. Finally, you must also call releaseConnection() when you are finished.
Here’s an example of using this class with the ClientRequest.get() method:
RESTEasy Client Framework | 175
Download at WoweBook.Com
ClientRequest request =
new ClientRequest("http://example.com/customers/{id}");
request.accept("application/xml")
.pathParameter("id", 333);
ClientResponse<Customer> response = request.get(Customer.class);
try {
if (response.getStatus() != 200)
throw new RuntimeException("Failed!");
Customer customer = response.getEntity();
} finally {
response.releaseConnection();
}
Authentication
The RESTEasy Client Framework runs on top of Apache HttpClient. If you need to
execute authenticated requests, you do so by configuring the Apache HttpClient backbone
RESTEasy uses. You first set up a DefaultHttpClient with the appropriate configuration
parameters set. Then you initialize an org.jboss.resteasy.client.core.exec
utors.ApacheHttpClient4Executor passing in the DefaultHttpClient instance you created.
This executor is used when instantiating ClientRequest objects. For example:
DefaultHttpClient client = new DefaultHttpClient();
client.getCredentialsProvider().setCredentials(
new AuthScope("example.com", 443),
new UsernamePasswordCredentials("bill", "geheim");
);
ApacheHttpClient4Executor executor =
new ApacheHttpClient4Executor(client);
ClientRequest request =
new ClientRequest("https://example.com/customers/{id}",
executor);
request.accept("application/xml")
.pathParameter("id", 333);
ClientResponse<Customer> response = request.get(Customer.class);
try {
if (response.getStatus() != 200)
throw new RuntimeException("Failed!");
Customer customer = response.getEntity();
} finally {
response.releaseConnection();
}

RESTEasy also supports using Apache HttpClient 3.1 and java.net.URLConnection as
a backbone if you can’t use Apache HttpClient 4.x.
176 | Chapter 13: RESTful Java Clients
Download at WoweBook.Com
Advantages and Disadvantages
Using something like RESTEasy’s Client Framework makes writing RESTful clients a
lot easier, as you can take advantage of the variety of content handlers available in the
Java community for JAX-RS. The biggest disadvantage of RESTEasy’s Client Framework
is that, although open source, it is not a standard. I mention it in this book not
only because it is the project I am currently leading, but also because JAX-RS implementations
like Jersey‡ and Apache CXF§ have very similar frameworks. There is a lot
of interest from the JAX-RS specification lead and expert group members to get a
standardized client framework baked into JAX-RS 2.0. I hope that by the time you finish
reading this chapter, the effort is already well under way!
分享到:
评论

相关推荐

    浅谈java调用Restful API接口的方式

    Java调用Restful API接口是Java开发中非常重要的一部分,了解Java调用Restful API接口的方式可以帮助开发者更好地理解和使用相关技术。本文将详细介绍Java调用Restful API接口的方式,包括使用HttpURLConnection、...

    RESTful Java Web Services

    REST(Representational State Transfer)是一种软件架构风格,最初由Roy Fielding在他的博士论文中提出。它定义了一种简单且灵活的方法来创建分布式系统,如Web服务。在《RESTful Java Web Services》一书中,作者...

    专门用来测试restFul的GUI客户端工具

    "jar"代表Java Archive,是一种可执行文件格式,包含了Java类、资源和其他组件,便于分发和运行。"with-dependencies"暗示这个JAR文件已经集成了所有依赖的库,可以直接运行,无需额外安装其他组件。 综上所述,这...

    httpclient和RestfuL风格上传下载文件

    HTTPClient是一个强大的HTTP客户端库,而RESTful是一种轻量级的、基于HTTP协议的软件架构风格,常用于构建Web服务。在分布式系统中,这两种技术常常结合使用,以实现各个节点间的高效数据交互。 **HTTPClient简介**...

    restful接口实现Demo

    RESTful接口是Web服务设计的一种常见模式,它遵循Representational State Transfer(表述性状态转移)原则,强调资源的表示和操作。在这个“restful接口实现Demo”中,我们可以通过Java技术来实现这样的接口,并通过...

    SSM整合 完美支持RESTful(Jsp和客户端 android ios ).docx

    RESTful是一种基于HTTP协议的软件设计风格,用于构建可伸缩的、易理解和扩展的网络应用程序。它的核心理念是通过统一资源标识符(URI)来定位资源,并通过GET、POST、PUT、DELETE这四个HTTP方法来对资源进行操作。 ...

    客户端与服务器SSL双向认证(客户端:java-服务端:java)

    SSL(Secure Sockets Layer)双向认证,也称为mutual SSL,是一种网络安全协议,它要求客户端和服务器双方在建立连接时都提供身份证明。这增强了通信的安全性,因为双方都需要验证对方的身份,防止中间人攻击和其他...

    c# 服务端调用RestFul Service的方法

    REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,基于约束条件和架构原则的运用。REST 架构风格的核心概念是“资源”(Resource),并通过 URL 来定位这些资源。RESTful API 使用 ...

    RESTFUL JAVA

    **REST(Representational State Transfer)** 是一种用于构建网络应用程序的架构风格,它利用了HTTP协议的核心功能来实现资源的高效管理和交互。在《RESTful Java with JAX-RS2.0》这本书中,作者Bill Burke深入...

    在同一个系统里用cxf 实现SOAP 协议和RESTful风格 两种类型的webservice接口

    总之,Apache CXF提供了一种高效的方式来实现SOAP和RESTful两种类型的Web服务接口。通过合理的配置和编码,开发者可以在同一系统中轻松地集成这两种服务风格,满足不同应用场景的需求。在实际项目中,根据服务的特性...

    RESTFUL_JAVA_WEB_SERVICES_THIRD_EDITION.pdf

    通过阅读这本书,读者将能够掌握RESTful服务的核心概念,使用Java实现高效的RESTful API,并具备设计健壮、可扩展的web服务的能力。无论你是初学者还是经验丰富的开发者,这本书都将提供宝贵的指导,帮助你在Java...

    CXF3.0+Spring3.2 RESTFul服务(下)

    CXF3.0.2与Spring3.2.14的组合为开发者提供了一种强大且灵活的方式来构建RESTful服务。通过合理的注解和配置,我们可以轻松地定义服务接口、处理请求和响应,以及实现JSON数据的交换。下载提供的`WbRest1`源代码,...

    JAXRS2.0REST客户端编程实例Java开发Java

    在Java开发中,JAX-RS(Java API for RESTful Web Services)是一种用于创建RESTful Web服务的标准API。JAX-RS 2.0是这个标准的第二版,它引入了许多新特性和改进,使得开发RESTful客户端和服务变得更加简单和高效。...

    java利用 xfire实现 webservices 服务端与客户端

    Java使用XFire实现Web服务(WebServices)是Java开发中的一种常见技术,它允许应用程序通过网络交换数据。XFire是一个轻量级、高性能的框架,它简化了在Java应用程序中创建和消费Web服务的过程。本篇文章将深入探讨...

    coap 协议实现(服务端+客户端)

    本项目提供了COAP协议的服务器端和客户端的Java实现,使得开发者能够快速构建基于COAP的物联网应用。 **COAP协议简介** COAP是基于UDP的协议,它借鉴了HTTP的模型,具有RESTful架构,支持GET、PUT、POST和DELETE等...

    RESTful Java Web Services (2009).pdf

    - **REST(Representational State Transfer)**:一种网络应用程序的设计风格和开发方式,基于约束条件和原则,利用HTTP协议来实现客户端与服务器之间的交互。 - **核心特点**: - 无状态:每次请求都包含理解该...

    Java+restful+Web+Service实战

    REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,基于HTTP协议,强调简洁、统一的接口设计,使Web服务更加轻量级和易于理解。 在本教程中,你将深入学习以下几个关键知识点: 1....

    服务端和客户端实现已经实现了用JAVA

    2. **Java Applets**:虽然现在已经不再推荐使用,但Java Applets曾是一种在浏览器中运行的Java程序,用于增强网页功能。 3. **Java Web Start**:Java Web Start允许用户从Web服务器下载并运行Java应用程序,提供...

Global site tag (gtag.js) - Google Analytics