JAX-RS is just an API! – JAX-RS只是一个API!

最后修改: 2017年 1月 18日


1. Overview


The REST paradigm has been around for quite a few years now and it’s still getting a lot of attention.


A RESTful API can be implemented in Java in a number of ways: you can use Spring, JAX-RS, or you might just write your own bare servlets if you’re good and brave enough. All you need is the ability to expose HTTP methods – the rest is all about how you organize them and how you guide the client when making calls to your API.

RESTful API可以通过多种方式在Java中实现:你可以使用Spring、JAX-RS,或者如果你足够优秀和勇敢,你也可以自己编写裸露的Servlets。你所需要的只是暴露HTTP方法的能力–剩下的就是你如何组织这些方法,以及你在调用API时如何引导客户端。

As you can make out from the title, this article will cover JAX-RS. But what does “just an API” mean? It means that the focus here is on clarifying the confusion between JAX-RS and its implementations and on offering an example of what a proper JAX-RS webapp looks like.

从标题可以看出,这篇文章将涉及JAX-RS。但 “只是一个API “是什么意思呢?它意味着这里的重点是澄清JAX-RS和它的实现之间的混淆,以及提供一个适当的JAX-RS网络应用的例子。

2. Inclusion in Java EE

2.包含在Java EE中

JAX-RS is nothing more than a specification, a set of interfaces and annotations offered by Java EE. And then, of course, we have the implementations; some of the more well known are RESTEasy and Jersey.

JAX-RS只不过是一种规范,是由Java EE提供的一组接口和注解。当然,我们还有一些实现;其中一些比较知名的是RESTEasyJersey

Also, if you ever decide to build a JEE-compliant application server, the guys from Oracle will tell you that, among many other things, your server should provide a JAX-RS implementation for the deployed apps to use. That’s why it’s called Java Enterprise Edition Platform.


Another good example of specification and implementation is JPA and Hibernate.


2.1. Lightweight Wars


So how does all this help us, the developers? The help is in that our deployables can and should be very thin, letting the application server provide the needed libraries. This applies when developing a RESTful API as well: the final artifact should not contain any information about the used JAX-RS implementation.

那么,所有这些对我们这些开发者有什么帮助呢?帮助在于,我们的部署品可以而且应该非常薄,让应用服务器提供所需的库。这一点在开发RESTful API时也适用:最终的工件不应包含任何关于所使用的JAX-RS实现的信息。

Sure, we can provide the implementation (here‘s a tutorial for RESTeasy). But then we cannot call our application “Java EE app” anymore. If tomorrow someone comes and says “Ok, time to switch to Glassfish or Payara, JBoss became too expensive!“, we might be able to do it, but it won’t be an easy job.

当然,我们可以提供实现(这里是一个RESTeasy的教程)。但这样我们就不能再把我们的应用程序称为 “Java EE应用程序”。如果明天有人过来说:”Ok,是时候换成Glassfish或Payara了,JBoss变得太贵了!“,我们也许能做到,但这并不是一件容易的事。

If we provide our own implementation we have to make sure the server knows to exclude its own – this usually happens by having a proprietary XML file inside the deployable. Needless to say, such a file should contain all sorts of tags and instructions that nobody knows nothing about, except the developers who left the company three years ago.


2.2. Always Know Your Server


We said so far that we should take advantage of the platform that we’re offered.


Before deciding on a server to use, we should see what JAX-RS implementation (name, vendor, version and known bugs) it provides, at least for Production environments. For instance, Glassfish comes with Jersey, while Wildfly or Jboss come with RESTEasy.


This, of course, means a little time spent on research, but it’s supposed to be done only once, at the beginning of the project or when migrating it to another server.


3. An Example


If you want to start playing with JAX-RS, the shortest path is: have a Maven webapp project with the following dependency in the pom.xml:

如果你想开始玩JAX-RS,最短的路径是:拥有一个Maven webapp项目,其pom.xml中的依赖关系如下。


We’re using JavaEE 7 since there are already plenty of application servers implementing it. That API jar contains the annotations that you need to use, located in package javax.ws.rs. Why is the scope “provided”? Because this jar doesn’t need to be in the final build either – we need it at compile time and it is provided by the server for the run time.

我们使用JavaEE 7,因为已经有很多应用服务器在实现它。那个API jar包含了你需要使用的注解,位于包javax.ws.rs中。为什么范围是 “提供”?因为这个jar也不需要在最终的构建中出现–我们在编译时需要它,它是由服务器为运行时提供的。

After the dependency is added, we first have to write the entry class: an empty class which extends javax.ws.rs.core.Application and is annotated with javax.ws.rs.ApplicationPath:


public class RestApplication extends Application {

We defined the entry path as being /api. Whatever other paths we declare for our resources, they will be prefixed with /api.


Next, let’s see a resource:


public class NotificationsResource {
    public Response ping() {
        return Response.ok().entity("Service online").build();

    public Response getNotification(@PathParam("id") int id) {
        return Response.ok()
          .entity(new Notification(id, "john", "test notification"))

    public Response postNotification(Notification notification) {
        return Response.status(201).entity(notification).build();

We have a simple ping endpoint to call and check if our app is running, a GET and a POST for a Notification (this is just a POJO with attributes plus getters and setters).


Deploy this war on any application server implementing JEE7 and the following commands will work:


curl http://localhost:8080/simple-jaxrs-ex/api/notifications/ping/

curl http://localhost:8080/simple-jaxrs-ex/api/notifications/get/1

curl -X POST -d '{"id":23,"text":"lorem ipsum","username":"johana"}' 
  --header "Content-Type:application/json"

Where simple-jaxrs-ex is the context-root of the webapp.


This was tested with Glassfish 4.1.0 and Wildfly 9.0.1.Final. Please note that the last two commands won’t work with Glassfish 4.1.1, because of this bug. It is apparently a known issue in this Glassfish version, regarding the serialization of JSON (if you have to use this server version, you’ll have to manage JSON marshaling on your own)

这是用Glassfish 4.1.0和Wildfly 9.0.1.Final测试的。请注意,由于这个错误,最后两个命令在Glassfish 4.1.1中无法工作。这显然是这个Glassfish版本中的一个已知问题,关于JSON的序列化(如果你必须使用这个服务器版本,你将不得不自己管理JSON marshaling)

4. Conclusion


At the end of this article, just keep in mind that JAX-RS is a powerful API and most (if not all) of the stuff that you need is already implemented by your web server. No need to turn your deployable into an unmanageable pile of libraries.


This write-up presents a simple example and things might get more complicated. For instance, you might want to write your own marshalers. When that’s needed, look for tutorials that solve your problem with JAX-RS, not with Jersey, Resteasy or other concrete implementation. It’s very likely that your problem can be solved with one or two annotations.