RESTEasy入门
RESTEasy入门
\
RESTEasy是JBoss的开源项目之一,是一个RESTful Web
Services框架。RESTEasy的开发者Bill
Burke同时也是JAX-RS的J2EE标准制定者之一。JAX-RS是一个JCP制订的新标准,用于规范基于HTTP的RESTful
Web Services的API。
\
我们已经有SOAP了,为什么需要Restful
WebServices?用Bill自己的话来说:”如果是为了构建SOA应用,从技术选型的角度来讲,我相信REST比SOAP更具优势。开发人员会意识到使用传统方式有进行SOA架构有多复杂,更不用提使用这些做出来的接口了。这时他们就会发现Restful
Web Services的光明之处。”
\
说了这么多,我们使用RESTEasy做一个项目玩玩看。首先创造一个maven1的web项目
Java代码 收藏代码
\
mvn archetype:create -DgroupId=org.bluedash \
-DartifactId=try-resteasy
-DarchetypeArtifactId=maven-archetype-webapp
\
\
准备工作完成后,我们就可以开始写代码了,假设我们要撰写一个处理客户信息的Web
Service,它包含两个功能:一是添加用户信息;二是通过用户Id,获取某个用户的信息,而交互的方式是标准的WebService形式,数据交换格式为XML。假设一条用户包含两个属性:Id和用户名。那么我们设计交换的XML数据如下:
Java代码 收藏代码
\
1
liweinan
\
\
首先要做的就是把上述格式转换成XSD2,网上有在线工具可以帮助我们完成这一工作3,在此不详细展开。使用工具转换后,生成如下xsd文件:
Java代码 收藏代码
\
version=”1.0” xmlns:xsd=”http://www.w3.org/2001/XMLSchema“>
\
\
有了xsd文件,我们便可以使用JDK自带工具的xjc将xsd转换成为Java的Class。将上述xsd文件存为
user.xsd,并使用如下命令进行转换:
Java代码 收藏代码
\
xjc user.xsd
\
执行结束后我们会得到一系列的类文件:
Java代码 收藏代码
\
Li-Weinans-MacBook-Pro:Desktop liweinan$ xjc user.xsd
parsing a schema…
compiling a schema…
generated/ObjectFactory.java
generated/UserType.java
\
\
这样,我们的XML格式的交换数据便转化为面向对像的Java类了,是不是感觉有点像Hibernate的ORM理念?没错,将XML映射成成面向对象的数据类,这个过程叫做XML
Binding,即XML绑定。这个过程也有J2EE标准,叫做JAXB4。而RESTEasy是全面支持JAXB的。可以说RESTEasy所支持的JAX-RS标准,当与JAXB标准结合在一起使用时,就可以发挥出最大优势,让程序员少写一堆一堆的代码。有关JAXB标准,会在
独立的篇章中
详细讨论,在此先不展开。总之我们将生成的Java类放进项目中等候使用。我们可以看一下UserType类的内容:
Java代码 收藏代码
\
package org.bluedash.resteasy;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
XmlAccessorType(XmlAccessType.FIELD)
XmlType(name = “userType”, propOrder = {
“id”,
“name”
})
public class UserType {
protected int id;
XmlElement(required = true)
protected String name;
/**
* Gets the value of the id property.
*
*/
public int getId() {
return id;
}
/**
* Sets the value of the id property.
*
*/
public void setId(int value) {
this.id = value;
}
/**
* Gets the value of the name property.
*
* return
* possible object is
* { link String }
*
*/
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* param value
* allowed object is
* { link String }
*
*/
public void setName(String value) {
this.name = value;
}
}
\
可以看到,XML格式就是通过一些JAXB的标记被映射成了Java类。我们没写什么代码,已经把数据模型定义清楚了。接下来我们撰写最核心的WebService
API。我们的WebService包含两个接口:一个是添加用户接口createUser,另一个是获取用户接口getUser:
Java代码 收藏代码
\
package org.bluedash.resteasy;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
Path(“/users”)
public class UserServlet {
private Map userStore =
new ConcurrentHashMap();
private AtomicInteger idGenerator = new AtomicInteger();
POST
Consumes(“application/xml”)
public Response createUser(UserType user) {
user.setId(idGenerator.incrementAndGet());
userStore.put(user.getId(), user);
System.out.println(user.getName() + “ created: “
+ user.getId());
return Response.created(URI.create(“/users/“
+ user.getId())).build();
}
GET
Path(“{id}”)
Produces(“application/xml”)
public UserType getUser( PathParam(“id”) int id) {
UserType u = userStore.get(id);
if (u == null) {
throw new WebApplicationException(
Response.Status.NOT_FOUND);
}
return u;
}
}
\
\
用几个简单的JAX-RS标记,便把普通的函数变成了WebService接口。而这些标记将由RESTEasy支持生效。接下来我们将要进行RESTEasy的配置工作。RESTEasy的配置方法有多种多样,可以和Spring等容器集成,也可以独立运行,因为我们用的Servlet的形式使RESTEasy进行工作,这也是最主流的方式,因此在这里使用web容器来加载它,首先定义一个配置类:
Java代码 收藏代码
\
package org.bluedash.resteasy;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class BluedashResteasyApplication extends Application {
private Set
singletons = new HashSet
();
private Set> classes = new HashSet>();
public BluedashResteasyApplication() {
// classes.add(UserServlet.class);
singletons.add(new UserServlet());
}
Override
public Set> getClasses() {
return classes;
}
Override
public Set
getSingletons() {
return singletons;
}
}
\
\
这个类扩展JAX-RS的Application接口,用于封装我们的WebService
API方法。我们可以看到JAX-RS支持两种封装方法,一种是classes封装,由容器管理WebServices类的实例化和销毁等动作,一个线程一个实例,开发者不需要关心线程安全问题。但这种方法可能比较浪费资源。如果开发者想自己管理线程安全,共线程共用一个WebServices实例,那么就用singletons封装。我们在这里用的singletons封装,这也就解释了为什么我们在
UserServlet中使用了ConcurrentHashMap和AtomicInteger这些保障线程安全的类。接下来就是在web.xml中启动RESTEasy:
Java代码 收藏代码
\
“-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”
Archetype Created Web Application
javax.ws.rs.core.Application
org.bluedash.resteasy.
BluedashResteasyApplication
org.jboss.resteasy.plugins.server.
servlet.ResteasyBootstrap
Resteasy
org.jboss.resteasy.plugins.server.servlet.
HttpServletDispatcher
Resteasy
/*
\
没错,就是这么简单,这样,我们的WebService就完成了!还差点什么呢?嗯,还差一个Test
Case来使用我们的WebService接口,并验证它的正确性,让我们来写一个TestUserAPI
Java代码 收藏代码
\
package org.bluedash.resteasy.test.integration.test;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import junit.framework.TestCase;
public class TestUserAPI extends TestCase {
public static final String USER_API =
public void testCreateUserAndGetUser() throws IOException {
URL url =
new URL(USER_API);
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
connection.setRequestMethod(“POST”);
connection.setRequestProperty(“Content-Type”,
“application/xml”);
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
connection.setConnectTimeout(1000);
String userXML = “liweinan”;
OutputStream os = connection.getOutputStream();
os.write(userXML.getBytes());
os.flush();
assertEquals(HttpURLConnection.HTTP_CREATED, connection
.getResponseCode());
connection.disconnect();
}
}
\
\
一切都已经准备就绪,最后我们要配置一下Maven,让它下载所需的RESTEasy等库,然后配置Maven使用Jetty
Web服务器,来把我们的服务和测试跑起来:
Java代码 收藏代码
\
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0
4.0.0
org.bluedash
try-resteasy
war
1.0-SNAPSHOT
try-resteasy Maven Webapp
JBossMavenRepo
JBoss Maven2 repo
true
false
junit
junit
4.4
test
org.jboss.resteasy
resteasy-jaxrs
1.2.RC1
org.jboss.resteasy
resteasy-jaxb-provider
1.2.RC1
javax.servlet
servlet-api
2.4
try-resteasy
org.apache.maven.plugins
maven-compiler-plugin
1.6
1.6
UTF-8
org.apache.maven.plugins
maven-surefire-plugin
**/integration/**
integration-tests
integration-test
test
false
none
**/integration/**
org.mortbay.jetty
maven-jetty-plugin
6.1.15
5
foo
9999
start-jetty
pre-integration-test
run
5
true
stop-jetty
post-integration-test
stop
\
\
有关Maven的配置就不详细展开了。配置完成后我们便可以运行单元测试,看看WebServices是否正确运行。执行下述命令
Java代码 收藏代码
\
mvn integration-test
\
执行结果如下:
Java代码 收藏代码
\
——————————————————-
T E S T S
——————————————————-
Running org.bluedash.resteasy.test.integration.test.TestUserAPI
liweinan created: 1
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:
0.372 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
\
\
可以看到,我们的测试按预期执行成功了。这篇文章中,我简单向大家介绍了RESTEasy的初步使用方法,希望对大家在架构SOA应用时,有所帮助。JAX-RS标准做为J2EE家庭中相对较新的一员,其应用前景是十分广阔的。
\