RESTEasy社区从 RESTEasy 2.0 版本开始包含进了一个新的Ajax组件:JS-API。通过使用JS-API,可以方便地调用RESTEasy服务端所提供的RESTFul WebService。本文将给出一个简单的例子,介绍这个组件的使用方法。
首先,我们使用Maven创建一个Web项目:
mvn archetype:create -DgroupId=org.bluedash \
-DartifactId=try-resteasy-jsapi -DarchetypeArtifactId=maven-archetype-webapp
如果上述命令执行成功,我们将得到一个名为"try-resteasy-jsapi"的Web项目。接下修改pom.xml, 引入使用RESTEasy所需的library,以及后续测试用的Jetty服务器:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.bluedash</groupId>
<artifactId>try-resteasy-jsapi</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>try-resteasy-jsapi Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>2.1.0.GA</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jsapi</artifactId>
<version>2.1.0.GA</version>
</dependency>
</dependencies>
<build>
<finalName>try-resteasy-jsapi</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.15</version>
<configuration>
<scanIntervalSeconds>5</scanIntervalSeconds>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>5</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
注意我们使用的是RESTEasy 2.1.0.GA 这个版本,它包括了RESTEasy JS-API组件。接下来,进入项目的根目录,执行maven命令,生成eclipse项目:
liweinan@mb:~/projs/try-resteasy-jsapi$ mvn eclipse:eclipse
生成好eclipse工程文件,我们便可以在eclipse中将项目引入,进行代码的开发:
项目引入eclipse后的情况如下:
仔细观察发现项目没有用于撰写源代码的目录,因此我们来创建一下,并重新生成eclipse工程:
liweinan@mb:~/projs/try-resteasy-jsapi$ mkdir -p src/main/java
liweinan@mb:~/projs/try-resteasy-jsapi$ mvn eclipse:eclipse
我们在eclipse里面刷新工程:
会发现多出来一个src/main/java目录:
我们将在这个目录中创建package及class。我们来做一个非常简单的Webservice服务,叫做Orders,我们仍然使用eclipse来创建这个Class:
Order.java的代码如下:
package net.bluedash.toy;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@Path("orders")
public class Orders {
@Path("{id}")
@GET
@Produces("text/plain")
public String getOrder(@PathParam("id") String id) {
return "Order Id: " + id;
}
}
这个WebService服务非常简单,用户访问/orders/{id}, 系统返回一串字符:Order Id: {id}。因为这篇文章的讲解重点是如何通过 RESTEasy JS-API,在Html页面通过Ajax的方式调用这个服务,所以服务端的逻辑越简单越好,方便进行说明。
接下是用RESTEasy的Application标准方式注册服务[1],创建OrdersApplication.java:
[1] 如果你对RESTEasy的基本使用方法不熟悉,请参考蓝点上面的 "另一篇文章":http://bluedash.net/spaces/RESTEasy
package net.bluedash.toy;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class OrdersApplication extends Application {
HashSet<Object> singletons = new HashSet<Object>();
public OrdersApplication() {
singletons.add(new Orders());
}
@Override
public Set<Class<?>> getClasses() {
HashSet<Class<?>> set = new HashSet<Class<?>>();
return set;
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
接下来是配置web.xml:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>javax.ws.rs.core.Application</param-name>
<param-value>net.bluedash.toy.OrdersApplication</param-value>
</context-param>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/resteasy</param-value>
</context-param>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
<servlet>
<servlet-name>RESTEasy JSAPI</servlet-name>
<servlet-class>org.jboss.resteasy.jsapi.JSAPIServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/resteasy/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>RESTEasy JSAPI</servlet-name>
<url-pattern>/rest-js</url-pattern>
</servlet-mapping>
</web-app>
注意我们在web.xml有一个关于 JS-API的配置:
...
<servlet>
<servlet-name>RESTEasy JSAPI</servlet-name>
<servlet-class>org.jboss.resteasy.jsapi.JSAPIServlet</servlet-class>
</servlet>
...
<servlet-mapping>
<servlet-name>RESTEasy JSAPI</servlet-name>
<url-pattern>/rest-js</url-pattern>
</servlet-mapping>
...
这个org.jboss.resteasy.jsapi.JSAPIServlet将会负责把我们的webservice服务映射至javascript脚本,而脚本的提供位置位于配置指向的/rest-js。我们在HTML页面当中,就可以方便地使用RESTEasy为我们生成的JS脚本,调用WebService接口。
代码编写及配置工作完成后,我们启动服务试试看:
liweinan@mb:~/projs/try-resteasy-jsapi$ mvn jetty:run
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building try-resteasy-jsapi Maven Webapp
[INFO] task-segment: [jetty:run]
[INFO] ------------------------------------------------------------------------
...
Jan 27, 2011 10:29:41 AM org.jboss.resteasy.spi.ResteasyDeployment
WARNING: The use of javax.ws.rs.core.Application is deprecated, please use javax.ws.rs.Application as a context-param instead
Jan 27, 2011 10:29:41 AM org.jboss.resteasy.spi.ResteasyDeployment
INFO: Deploying javax.ws.rs.core.Application: class net.bluedash.toy.OrdersApplication
Jan 27, 2011 10:29:41 AM org.jboss.resteasy.spi.ResteasyDeployment
INFO: Adding singleton resource net.bluedash.toy.Orders from Application javax.ws.rs.core.Application
2011-01-27 10:29:41.729::INFO: Started [email protected]:8080
[INFO] Started Jetty Server
[INFO] Starting scanner at interval of 5 seconds.
打开浏览器,输入:
http://127.0.0.1:8080/try-resteasy-jsapi/resteasy/orders/1
这样直接访问我们的Webservice服务,输出结果如下:
我们要怎么样通过Ajax的方式访问到这个服务呢?实际上,通过 web.xml 的配置,RESTEasy的JS-API已经帮我们生成了所需的JS脚本,可以访问生成的脚本试试看:
http://127.0.0.1:8080/try-resteasy-jsapi/rest-js
可以看到,RESTEasy已经为我们生成好了所需的Ajax调用所需JS脚本,接下来是看看如何使用它。我们在项目的index.jsp里面添加代码:
<html>
<body>
<h2>RESTEasy JS-API Demo</h2>
<form>
<input type='button' onclick='callJsApi();' value='Get Orders'/>
</form>
<script src="/examples-jsapi/rest-js" type="text/javascript"></script>
<script type="text/javascript">
var global_order_id = 0;
function callJsApi() {
var order = Orders.getOrder({id: global_order_id++});
alert(order);
}
</script>
</body>
</html>
首先,我们引入了resteasy js-api为我们生成的调用脚本:
<script src="/examples-jsapi/rest-js" type="text/javascript"></script>
然后,我们便可以直接访问我们的Webservice服务:
var order = Orders.getOrder({id: global_order_id++});
可以看到RESTEasy已经为我们创建了Orders对象,而调用方法也和接口中的一致。我们把服务重启,试试看效果:
我将上述代码形成了一个项目,叫做example-jsapi,提交进了RESTEasy的代码仓库,位于examples目录。如果你签出最新版本的 RESTEasy,可以玩玩看这个项目。
有关RESTEasy JS-API的更多使用方法,请参考:
http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html/AJAX_Client.html