原文:https://docs.jboss.org/author/display/AS7/Java+API+for+RESTful+Web+Services+(JAX-RS)

Content

Tutorial Overview

This chapter describes the Java API for RESTful web services (JAX-RS, defined in JSR331). RESTEasy is an portable implementation of this specification which can run in any Servlet container. Tight integration with JBoss Application Server is available for optimal user experience in that environment. While JAX-RS is only a server-side specification, RESTeasy has innovated to bring JAX-RS to the client through the RESTEasy JAX-RS Client Framework.

Detailed documentation on RESTEasy is available here.
The source for this tutorial is in github repository git://github.com/tdiesler/javaee-tutorial.git

OpenShift, is a portfolio of portable cloud services for deploying and managing applications in the cloud. This tutorial shows how to deploy a RESTful web service on the free OpenShift Express JavaEE cartridge that runsJBossAS 7.

An application running on Android shows how to leverage JBoss technology on mobile devices. Specifically, we show how use the RESTEasy client API from an Android device to integrate with a RESTful service running on a JBossAS 7 instance in the cloud.

The following topics are addressed

  • What are RESTful web services
  • Creating a RESTful server endpoint
  • Deploying a RESTful endpoint to a JBossAS instance in the cloud
  • RESTEasy client running on an Android mobile device

What are RESTful Web Services?

Coming Soon
This section is still under development.

RESTful web services are designed to expose APIs on the web. REST stands for Representational State Transfer. It aims to provide better performance, scalability, and flexibility than traditinoal web services, by allowing clients to access data and resources using predictable URLs. Many well-known public web services expose RESTful APIs.

The Java 6 Enterprise Edition specification for RESTful services is JAX-RS. It is covered by JSR-311 (http://jcp.org/jsr/detail/311.jsp). In the REST model, the server exposes APIs through specific URIs (typically URLs), and clients access those URIs to query or modify data. REST uses a stateless communication protocol. Typically, this is HTTP.

The following is a summary of RESTful design principles:

  • A URL is tied to a resource using the @Path annotation. Clients access the resource using the URL.
  • Create, Read, Update, and Delete (CRUD) operations are accessed via PUTGETPOST, and DELETE requests in the HTTP protocol.
    • PUT creates a new resource.
    • DELETE deletes a resource.
    • GET retrieves the current state of a resource.
    • POST updates a resources's state.
  • Resources are decoupled from their representation, so that clients can request the data in a variety of different formats.
  • Stateful interactions require explicit state transfer, in the form of URL rewriting, cookies, and hidden form fields. State can also be embedded in response messages.

Creating a RESTful endpoint

A RESTful endpoint is deployed as JavaEE web archive (WAR). For this tutorial we use a simple library application to manage some books. There are two classes in this application:

  • Library
  • Book

The Book is a plain old Java object (POJO) with two attributes. This is a simple Java representation of a RESTful entity.

public class Book {
 
    private String isbn;
    private String title;
 
    ...
}

The Library is the RESTful Root Resource. Here we use a set of standard JAX-RS annotations to define

  • The root path to the library resource
  • The wire representation of the data (MIME type)
  • The Http methods and corresponding paths
@Path("/library")
@Consumes({ "application/json" })
@Produces({ "application/json" })
public class Library {
 
    @GET
    @Path("/books")
    public Collection<Book> getBooks() {
    ...
    }
 
    @GET
    @Path("/book/{isbn}")
    public Book getBook(@PathParam("isbn") String id) {
    ...
    }
 
    @PUT
    @Path("/book/{isbn}")
    public Book addBook(@PathParam("isbn") String id, @QueryParam("title") String title) {
    ...
    }
 
    @POST
    @Path("/book/{isbn}")
    public Book updateBook(@PathParam("isbn") String id, String title) {
    ...
    }
 
    @DELETE
    @Path("/book/{isbn}")
    public Book removeBook(@PathParam("isbn") String id) {
    ...
    }
}

The Library root resource uses these JAX-RS annotations:

Annotation Description
@Path Identifies the URI path that a resource class or class method will serve requests for
@Consumes Defines the media types that the methods of a resource class can accept
@Produces Defines the media type(s) that the methods of a resource class can produce
@GET Indicates that the annotated method responds to HTTP GET requests
@PUT Indicates that the annotated method responds to HTTP PUT requests
@POST Indicates that the annotated method responds to HTTP POST requests
@DELETE Indicates that the annotated method responds to HTTP DELETE requests

For a full description of the available JAX-RS annotations, see the JAX-RS API documentation.

Package and build the endpoint

To package the endpoint we create a simple web archive and include a web.xml with the following content

Review
AS7-1674 Remove or explain why web.xml is needed for RESTful endpoints
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <servlet-mapping>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

The root context is defined in jboss-web.xml

<jboss-web>
  <context-root>jaxrs-sample</context-root>
</jboss-web>

The code for the JAX-RS part of this tutorial is available on https://github.com/tdiesler/javaee-tutorial/tree/master/jaxrs. In this step we clone the repository and build the endpoint using maven. There are a number of JAX-RS client tests that run against a local JBossAS 7 instance. Before we build the project, we set the JBOSS_HOME environment variable accordingly.

Arquillian, the test framework we use throughout this tutorial, can manage server startup/shutdown. It is however also possible to startup the server instance manually before you run the tests. The latter allows you to look at the console and see what log output the deployment phase and JAX-RS endpoint invocations produce.

$ git clone git://github.com/tdiesler/javaee-tutorial.git
Cloning into javaee-tutorial...
 
$ cd javaee-tutorial/jaxrs
$ export JBOSS_HOME=~/workspace/jboss-as-7.0.1.Final
$ mvn install
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] JavaEE Tutorial - JAX-RS .......................... SUCCESS [1.694s]
[INFO] JavaEE Tutorial - JAX-RS Server ................... SUCCESS [2.392s]
[INFO] JavaEE Tutorial - JAX-RS Client ................... SUCCESS [7.304s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12.142s

Deploy the endpoint to OpenShift

First we need to create a free OpenShift Express account and select the JavaEE cartridge that runs JBossAS 7. Once we have received the confirmation email from OpenShift we can continue to create our subdomain and deploy the RESTful endpoint. A series of videos on the OpenShift Express page shows you how to do this. There is also an excellent quick start document that you have access to after login.

For this tutorial we assume you have done the above and that we can continue by creating the OpenShift application. This step sets up your JBossAS 7 instance in the cloud. Additionally a Git repository is configured that gives access to your deployed application.

$ rhc-create-app -a tutorial -t jbossas-7.0
Password:
 
Attempting to create remote application space: tutorial
Successfully created application: tutorial
Now your new domain name is being propagated worldwide (this might take a minute)...
 
Success!  Your application is now published here:
 
 
The remote repository is located here:
 
    ssh://79dcb9db5e134cccb9d1ba33e6089667@tutorial-tdiesler.rhcloud.com/~/git/tutorial.git/

Next, we can clone the remote Git repository to our local workspace

$ git clone ssh://79dcb9db5e134cccb9d1ba33e6089667@tutorial-tdiesler.rhcloud.com/~/git/tutorial.git
Cloning into tutorial...
remote: Counting objects: 24, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 24 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (24/24), 21.84 KiB, done.
 
ls -1 tutorial
deployments
pom.xml
README
src

Because we want to deploy an already existing web application, which we'll build in the next step, we can safely remove the source artefacts from the repository.

$ rm -rf tutorial/src tutorial/pom.xml

Now we copy the JAX-RS endpoint webapp that we build above to the 'deployments' folder and commit the changes.

$ cp javaee-tutorial/jaxrs/server/target/javaee-tutorial-jaxrs-server-1.0.0-SNAPSHOT.war tutorial/deployments
$ cd tutorial; git commit -a -m "Initial jaxrs endpoint deployment"
[master be5b5a3] Initial jaxrs endpoint deployment
 7 files changed, 0 insertions(+), 672 deletions(-)
 create mode 100644 deployments/javaee-tutorial-jaxrs-server-1.0.0-SNAPSHOT.war
 delete mode 100644 pom.xml
 delete mode 100644 src/main/java/.gitkeep
 delete mode 100644 src/main/resources/.gitkeep
 delete mode 100644 src/main/webapp/WEB-INF/web.xml
 delete mode 100644 src/main/webapp/health.jsp
 delete mode 100644 src/main/webapp/images/jbosscorp_logo.png
 delete mode 100644 src/main/webapp/index.html
 delete mode 100644 src/main/webapp/snoop.jsp
 
$ git push origin
Counting objects: 6, done.
...
remote: Starting application...Done

You can now use curl or your browser to see the JAX-RS endpoint in action. The following URL lists the books that are currently registered in the library.

[
{"title":"The Judgment","isbn":"001"},
{"title":"The Stoker","isbn":"002"},
{"title":"Jackals and Arabs","isbn":"003"},
{"title":"The Refusal","isbn":"004"}
]

Building the mobile client

The source associated with this tutorial contains a fully working mobile client application for the Android framework. If not done so already please follow steps described in Installing the SDK. In addition to the Android SDK, I recommend installing the m2eclipse and the EGit plugin to Eclipse.

First, go to File|Import... and choose "Existing Maven Projects" to import the tutorial sources

You project view should look like this

Then go to File|New|Android Project and fill out the first wizard page like this

Click Finish. Next, go to Project|Properties|Build Path|Libraries and add these external libraries to your android project.

You final project view should look like this

To run the application in the emulator, we need an Android Virtual Device (AVD). Go to Window|Android SDK and AVD Manager and create a new AVD like this

Now go to Run|Configuration to create a new run configuration for the client app.

Now you should be able to launch the application in the debugger. Right click on the javaee-tutorial-jaxrs-android project and select Debug As|Android Application. This should launch the emulator, which now goes though a series of boot screens until it eventually displays the Android home screen. This will take a minute or two if you do this for the first time.

When you unlock the home screen by dragging the little green lock to the right. You should see the the running JAX-RS client application.

Finally, you need to configure the host that the client app connects to. This would be the same as you used above to curl the library list. In the emulator click Menu|Host Settings and enter the host address of your OpenShift application.

When going back to the application using the little back arrow next to Menu, you should see a list of books.

You can now add, edit and delete books and switch between your browser and the emulator to verify that the client app is not cheating and that the books are in fact in the cloud on your JBossAS 7 instance.

In Eclipse you can go to the Debug perspective and click on the little Android robot in the lower right corner. This will display the LogCat view, which should display log output from that Android system as well as from this client app

08-30 09:05:46.180: INFO/JaxrsSample(269): removeBook: Book [isbn=1234, title=1234]
08-30 09:05:46.210: INFO/JaxrsSample(269): requestURI: http://tutorial-tdiesler.rhcloud.com:80/jaxrs-sample/library
08-30 09:05:46.860: INFO/global(269): Default buffer size used in BufferedInputStream constructor. It would be better to be explicit if an 8k buffer is required.
08-30 09:05:46.920: INFO/JaxrsSample(269): getBooks: [Book [isbn=001, title=The Judgment], Book [isbn=002, title=The Stoker], Book [isbn=003, title=Jackals and Arabs], Book [isbn=004, title=The Refusal]]

Exploring the mobile client

There is a lot to writing high quality mobile applications. The goal of this little application is to get you started with JBossAS 7 / Android integration. There is also a portable approach to writing mobile applications. A popular one would be through PhoneGap. With PhoneGap you write your application in HTML+CSS+Java Script. It then runs in the browser of your mobile device. Naturally, not the full set of mobile platform APIs would be available through this approach.

The JAX-RS client application uses an annotated library client interface

@Consumes({ "application/json" })
@Produces({ "application/json" })
public interface LibraryClient {
 
    @GET
    @Path("/books")
    public List<Book> getBooks();
 
    @GET
    @Path("/book/{isbn}")
    public Book getBook(@PathParam("isbn") String id);
 
    @PUT
    @Path("/book/{isbn}")
    public Book addBook(@PathParam("isbn") String id, @QueryParam("title") String title);
 
    @POST
    @Path("/book/{isbn}")
    public Book updateBook(@PathParam("isbn") String id, String title);
 
    @DELETE
    @Path("/book/{isbn}")
    public Book removeBook(@PathParam("isbn") String id);
}

There are two implementations of this interface available.

  • LibraryHttpclient
  • LibraryResteasyClient

The first uses APIs that are available in the Android SDK natively. The code is much more involved, but there would be no need to add external libraries (i.e. resteasy, jackson, etc). The effect is that the total size of the application is considerably smaller in size (i.e. 40k)

@Override
public List<Book> getBooks() {
    List<Book> result = new ArrayList<Book>();
    String content = get("books");
    Log.d(LOG_TAG, "Result content:" + content);
    if (content != null) {
        try {
            JSONTokener tokener = new JSONTokener(content);
            JSONArray array = (JSONArray) tokener.nextValue();
            for (int i = 0; i < array.length(); i++) {
                JSONObject obj = array.getJSONObject(i);
                String title = obj.getString("title");
                String isbn = obj.getString("isbn");
                result.add(new Book(isbn, title));
            }
        } catch (JSONException ex) {
            ex.printStackTrace();
        }
    }
    Log.i(LOG_TAG, "getBooks: " + result);
    return result;
}
 
private String get(String path) {
    try {
        HttpGet request = new HttpGet(getRequestURI(path));
        HttpResponse res = httpClient.execute(request);
        String content = EntityUtils.toString(res.getEntity());
        return content;
    } catch (Exception ex) {
        ex.printStackTrace();
        return null;
    }
}

The second implementation uses the fabulous RESTEasy client proxy to interact with the JAX-RS endpoint. The details of Http connectivity and JSON data binding is transparently handled by RESTEasy. The total size of the application is considerably bigger in size (i.e. 400k)

@Override
public List<Book> getBooks() {
    List<Book> result = new ArrayList<Book>();
    try {
        result = getLibraryClient().getBooks();
    } catch (RuntimeException ex) {
        ex.printStackTrace();
    }
    Log.i(LOG_TAG, "getBooks: " + result);
    return result;
}

Stay tuned for an update on a much more optimized version of the RESTEasy mobile client. Feasible is also a RESTEasy JavaScript library that would enable the portable PhoneGap approach.

jboss7 Java API for RESTful Web Services (JAX-RS) 官方文档的更多相关文章

  1. JAX-RS -- Java API for RESTful Web Services

    Java EE 6 引入了对 JSR-311 的支持.JSR-311(JAX-RS:Java API for RESTful Web Services)旨在定义一个统一的规范,使得 Java 程序员可 ...

  2. Jersey the RESTful Web Services in Java

    Jersey 是一个JAX-RS的实现, JAX-RS即Java API for RESTful Web Services, 支持按照表述性状态转移(REST)架构风格创建Web服务. REST 中最 ...

  3. 使用 Spring 3 来创建 RESTful Web Services

    来源于:https://www.ibm.com/developerworks/cn/web/wa-spring3webserv/ 在 Java™ 中,您可以使用以下几种方法来创建 RESTful We ...

  4. RESTful Web Services测试工具推荐

    命令行控的最爱:cURL cURL是一个很强大的支持各种协议的文件传输工具,用它来进行RESTful Web Services的测试简直是小菜一碟.这个工具基本上类Unix操作系统(各种Linux.M ...

  5. 使用 Spring 3 来创建 RESTful Web Services(转)

    使用 Spring 3 来创建 RESTful Web Services 在 Java™ 中,您可以使用以下几种方法来创建 RESTful Web Service:使用 JSR 311(311)及其参 ...

  6. 基于Spring设计并实现RESTful Web Services(转)

    基于Spring设计并实现RESTful Web Services 在本教程中,你将会使用Spring来创建一个具有生产力的RESTful网络服务. 为什么用RESTful网络服务? 从和Amazon ...

  7. Spring 3 来创建 RESTful Web Services

    Spring 3 创建 RESTful Web Services 在 Java™ 中,您可以使用以下几种方法来创建 RESTful Web Service:使用 JSR 311(311)及其参考实现 ...

  8. RESTful Web Services: A Tutorial--reference

    As REST has become the default for most Web and mobile apps, it's imperative to have the basics at y ...

  9. Spring Boot - Building RESTful Web Services

    Spring Boot Building RESTful Web Services https://www.tutorialspoint.com/spring_boot/spring_boot_bui ...

随机推荐

  1. php之框架增加日志记录功能类

    <?php /* 思路:给定文件,写入读取(fopen ,fwrite……) 如果大于1M 则重写备份 传给一个内容, 判断大小,如果大于1M,备份 小于则写入 */ class Log{ // ...

  2. jsp注释方式

    1,HTML的注释方法 <!--...add your comments here...--> 说明:使用该注释方法,其中的注释内容在客户端浏览中是看不见的.但是查看源代码时,客户是可以看 ...

  3. 那些年被我坑过的Python——一夫当关 第十三章(堡垒机初步设计)

      堡垒机架构 堡垒机的主要作用权限控制和用户行为审计,堡垒机就像一个城堡的大门,城堡里的所有建筑就是你不同的业务系统 , 每个想进入城堡的人都必须经过城堡大门并经过大门守卫的授权,每个进入城堡的人必 ...

  4. how to use a xml_id in field domain

    "[('parent_id','child_of', %(other_module.xml_id)d)]"

  5. bzoj2395: [Balkan 2011]Timeismoney

    Description      有n个城市(编号从0..n-1),m条公路(双向的),从中选择n-1条边,使得任意的两个城市能够连通,一条边需要的c的费用和t的时间,定义一个方案的权值v=n-1条边 ...

  6. phread_con_wait和pthread_mutex_lock实现的生产者消费者模型

    条件变量是利用线程间共享的全局变量进行同步的一种机制, 主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起: 另一个线程使"条件成立"(给出条件成立信号 ...

  7. 带你走进EJB--MDB实现发送邮件(1)

    在实际的项目中我们有这样的需求,用户注册网站成功之后系统会自动的给注册用户发送注册成功通知邮件,而发送通知邮件的具体过程我们可以通过MDB来实现. 在用MDB来实现发送通知过程之前我们需要先了解一下J ...

  8. Linux [Ubuntu 12.0.1] 常用命令

    1.文件名颜色的含义1)默认色代表普通文件.例:install.log2)绿色代表可执行文件.例:rc.news3)红色代表tar包 文件. 例:vim-7.1.tar.bz24)蓝色代表目录文件. ...

  9. 「Poetize3」绿豆蛙的归宿

    描述 Description 给出一个有向无环图,起点为1终点为N,每条边都有一个长度,并且从起点出发能够到达所有的点,所有的点也都能够到达终点.绿豆蛙从起点出发,走向终点.到达每一个顶点时,如果有K ...

  10. wpa_cli与wpa_supplicant的交互命令

    1)通过adb命令行,可以直接打开supplicant,从而运行wpa_cli,可以解决客户没有显示屏而无法操作WIFI的问题,还可以避免UI的问题带到driver.进一步来说,可以用在很多没有键盘输 ...