如何使用wink框架
Apache Wink是一个Apache孵化器项目,可用于创建和使用REST Web服务。 使用REST Web服务,客户端和服务之间的交互被限制为一组预定义的操作,并且客户端-服务器交互的复杂性被限制为客户端和服务之间交换的资源表示。 这种方法使您可以构建可互操作,可伸缩且可靠的基于REST的分布式超媒体系统。
本文展示了如何使用Apache Wink以及Eclipse IDE和Maven项目管理工具来开发,部署和运行RESTful Web服务。
Web服务的REST方法
用于设计Web服务的REST方法将客户端和服务之间的交互限制为一组创建,读取,更新,删除(CRUD)操作。 这些操作直接映射到HTTP方法,尤其是POST
, GET
, PUT
和DELETE
。 尽管RESTful风格与HTTP协议无关,但本文假定HTTP用于客户端和服务之间的通信。
REST Web服务对资源执行CRUD操作。 客户端与REST服务交换资源状态的表示。 表示使用的数据格式在HTTP请求或响应的标头中指定-XML和JSON是广泛使用的格式。 数据格式可能因一个操作而异。 例如,用于创建资源的数据格式与用于读取资源的格式不同。 REST服务维护资源的状态,但是与Servlet不同,它不维护客户端会话信息。
REST方法使您可以构建可互操作,可伸缩且可靠的基于REST的分布式系统。 例如, GET
, PUT
和DELETE
方法是幂等的,这意味着多次执行它们的结果与一次执行相同。 因为GET
操作不会更改资源状态,所以可以缓存GET
请求的结果以加快请求-响应周期。
JAX-RS为通过HTTP协议的RESTful Java Web服务定义了API。 JAX-RS实现包括Apache Wink,Sun Jersey和JBoss RESTEasy。 本文使用Apache Wink。
JAX-RS利用Java注释的功能来使用注释执行以下操作:
- 将HTTP方法和URI绑定到Java类的方法
- 从URI或HTTP标头注入元素作为方法参数
- 将HTTP消息的主体与Java类型相互转换
- 将URI模式绑定到Java类和方法-@
@Path
批注 - 将HTTP操作绑定到Java方法-
@GET
,@GET
@POST
,@GET
@PUT
和@DELETE
批注
JAX-RS还提供了用于构建新功能的框架。 例如,对于自定义数据格式,程序员可以开发消息读取器,并进行编写以将Java对象编组到HTTP消息中或从HTTP消息中解编出来。
在本文中,您将使用Eclipse和Maven下载Apache Wink,运行Apache Wink中包含的HelloWorld示例,然后将自己的REST Web服务创建为Eclipse项目。
使用Eclipse获取Apache Wink
在本节中,您将Eclipse与Maven Integration for Eclipse(称为m2eclipse )和Subclipse插件一起使用,以安装Apache Wink。 (M2eclipse提供了从Eclipse对Maven的访问; Subclipse提供了对Subversion存储库的访问。)您还可以将Eclipse用作构建和运行Web服务的平台。
先决条件
在获取Apache Wink之前,请下载并安装以下软件包( 有关下载URL,请参阅参考资料):
- Java软件开发套件(JDK)版本6.设置JAVA_HOME环境变量,并将其添加到路径%JAVA_HOME%\ bin(在Windows®中)或$ JAVA_HOME / bin(在Linux®中)。
- Apache Tomcat 6.0版。 将CATALINA_HOME环境变量设置为指向安装目录。
- 用于Java™平台的Eclipse IDE,企业版(Java EE)开发人员。 在撰写本文时,当前版本是Eclipse Galileo。
安装Subclipse
要使用Eclipse管理支持Maven的项目,请安装Eclipse插件Subclipse和m2eclipse。 要安装Subclipse插件,请执行以下步骤:
- 启动Eclipse。
- 点击菜单栏中的帮助 ,然后选择安装新软件 。
- 在“ 可用软件”窗口中,单击添加 。
- 在“ 添加站点”窗口中,键入:
Name: Subclipse Location: http://subclipse.tigris.org/update_1.6.x/
然后单击“ 确定” 。
- 在可用软件窗口中,选择Subclipse的(必需的)和SVNKit客户端适配器(不是必需的) 的Subclipse下复选框,如图图1 ,然后点击下一步 。
图1.安装Subclipse插件
- 在“ 安装详细信息”窗口中,单击“ 下一步” 。
- 在“ 查看许可证”窗口中,查看许可证,接受许可证协议的条款,然后单击“ 完成” 。
- 单击“ 是”以重新启动Eclipse。
安装m2eclipse
要安装m2eclipse插件,请执行与Subclipse插件相同的操作,但以下情况除外:
- 在“ 添加站点”窗口中,键入:
Name: Maven Integration for Eclipse Location: http://m2eclipse.sonatype.org/update/
然后单击“ 确定” 。
- 在“ 可用软件”窗口中,选中“ Eclipse的Maven集成(必需)和Subclipse的Maven SCM处理程序(可选)”复选框, 如图2所示,然后单击“ 下一步” 。
图2.安装m2eclipse插件
获取Apache Wink
现在,您可以使用Eclipse从存储库中检出Apache Wink示例,将所需的Java归档(JAR)文件(包括Apache Wink JAR文件)下载到本地存储库,并构建并运行Apache Wink HelloWorld示例。 为此,请执行以下步骤:
- 在Eclipse中,选择“ 文件”>“导入”以启动“导入向导”。
- 在“ 选择向导”页面上的“ 选择和导入源”框中,键入
maven
。 - 在“ Maven”下 ,选择“ 实现Maven项目” ,然后单击“ 下一步” 。
- 在“ 选择Maven工件”向导页面上,单击添加 。
- 在“ 添加依赖项”页面上,在“ 输入groupId,artifactId”框中键入
org.apache.wink.example
。
注意: 工件是Maven中使用的术语,指的是版本化并存储在存储库中的软件包的层次结构。 - 在Search Results区域中,选择org.apache.wink.example apps , 如图3所示,然后单击OK 。
图3. org.apache.wink.example组中的应用程序工件
- 在“ 选择Maven工件”向导页面上,单击“ 下一步” ,然后单击“ 完成” 。
- 在“ Maven项目”向导页面上,仅选择/pom.xml复选框,然后单击完成 。
Maven通过从远程存储库下载工件并构建本地存储库来解决工件的所有依赖关系。 Maven的优点之一是它处理传递依赖。 因此,在Maven项目对象模型(POM)文件中,您只需要声明工件的直接依赖关系,Maven会为您解析更高阶的依赖关系。
完成上述步骤8后,将创建一个Eclipse项目,其中包含Apache Wink示例的apps
模块中的代码。 在Eclipse的Project Explorer视图中浏览项目文件。
Apache Wink HelloWorld服务
让我们检查一下apps
模块中的HelloWorld
Java类。 在Project Explorer视图中,单击apps> HelloWorld> src> main ,然后打开文件HelloWorld.java,其骨架如清单1所示。
清单1. HelloWorld.java文件
package org.apache.wink.example.helloworld;
...
@Path("/world")
public class HelloWorld {
public static final String ID = "helloworld:1";
@GET
@Produces(MediaType.APPLICATION_ATOM_XML)
public SyndEntry getGreeting() {
SyndEntry synd = new SyndEntry(new SyndText("Hello World!"), ID, new Date());
return synd;
}
}
HelloWorld是一个JAX-RS 资源 (或服务),由类定义之前的@Path("/world")
批注指示。 字符串"/world"
是资源的相对根URI。 JAX-RS将与相对URI "/world"
匹配的HTTP请求路由到HelloWorld
类的方法。
HelloWorld
类的唯一方法getGreeting
具有@GET
批注,这意味着它将处理HTTP GET
请求。
@Produces(MediaType.APPLICATION_ATOM_XML)
注释指示HTTP响应的媒体类型,即HTTP响应的标头中Content-Type
字段的值。
与相对根URI "/world"
相关联的绝对URI由部署描述符web.xml
的设置确定,该描述符位于HelloWorld / src / main / webapp / WEB-INF下, 如图4所示。
图4. HelloWorld应用程序的部署描述符
注意,URI模式/rest/*
绑定到restSdkService
servlet。 该servlet的上下文路径是HelloWorld
,它由HelloWorld / pom.xml文件中的<finalName>
元素定义。 因此, HelloWorld
资源的绝对URI为:
http://host:port/HelloWorld/rest/world
图4中的servlet名称restSdkService
指的是org.apache.wink.server.internal.servlet.RestServlet
Apache Wink类,如图中的<servlet>
元素所示。 使用初始化参数applicationConfigLocation
将RestServlet
类传递给HelloWorld
类的名称,该参数依次指向位于HelloWorld / src / main / webapp / WEB-INF文件夹中web.xml旁边的文件应用程序 。 应用程序文件只有一行,它是HelloWorld
资源的限定名称:
org.apache.wink.example.helloworld.HelloWorld
RestServlet
servlet可以在不了解JAX-RS的servlet容器中运行,从而支持将JAX-RS服务轻松部署到不了解JAX-RS的容器。
现在,让我们构建HelloWorld服务,然后在Tomcat 6.0 Servlet容器中部署并运行它。
建立HelloWorld
在Eclipse中,您可以使用m2eclipse插件来构建,部署和运行HelloWorld。 首先,编译源代码并为HelloWorld服务构建Web存档(WAR)文件。 要构建服务,请指示m2eclipse执行安装生命周期阶段。 (执行一个Maven生命周期阶段触发项目生命周期之前的阶段的执行。)执行安装阶段,在项目浏览器视图右击的HelloWorld,然后单击运行方式> Maven的安装 ,如图图5 。
图5.执行Maven安装阶段
Maven下载所有依赖项(从中央存储库http://repo1.maven.org/maven2或从镜像存储库下载),并在Windows®或$ HOME / .m2中的%HOMEPATH%\。m2 \ repository下构建本地存储库。 / Linux中的/ repository。 Maven执行的操作记录在Eclipse窗口的控制台视图中。
如果安装阶段成功完成,则将在目标目录下构建WAR文件HelloWorld.war并将其部署到本地存储库,并且控制台视图将显示消息“构建成功”。
将HelloWorld部署到Tomcat
您使用Maven的Tomcat插件。 (Maven和Eclipse一样,通过插件提供了许多功能。)您必须通过指定插件的groupId
和artifactId
来告诉Maven Tomcat插件的位置, 如图6所示(第45行-在pom.xml中为46)。
图6. Tomcat Maven插件
您还需要告诉Maven用于访问Tomcat管理器应用程序的用户名和密码。 Maven使用管理器应用程序指示Tomcat部署或取消部署Web应用程序。 告诉Maven身份验证信息,如下所示:
- 声明
tomcat-maven-plugin
工件的Tomcat服务器配置(称为tomcat-localhost
, 如图6所示(pom.xml中的第47-49行)。 - 在Maven设置文件settings.xml中定义此配置(在Windows中位于%HOMEPATH%\。m2 \下,在Linux中位于$ HOME / .m2下),如清单2所示。
清单2. Maven settings.xml文件
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <servers> <server> <id>tomcat-localhost</id> <username>admin</username> <password>admin</password> </server> </servers> </settings>
现在,您准备将服务部署到Tomcat。 这是通过执行Tomcat插件的重新部署目标来完成的。 (与生命周期阶段不同,生命周期阶段会自动执行生命周期的前几个阶段,而Maven 目标是由其自身执行的。)要执行重新部署目标,请执行以下步骤:
- 如图7所示,将身份验证信息插入Tomcat配置文件conf / tomcat-users.xml(位于CATALINA_HOME下),但是使用admin以外的密码。
图7. Tomcat身份验证配置
- 通过运行以下命令启动Tomcat:
In Windows: %CATALINA_HOME%\bin\catalina.bat start In Linux: $CATALINA_HOME/bin/catalina.sh start
- 执行
maven tomcat:redeploy
,它使用Tomcat管理器应用程序将HelloWorld.war部署到Tomcat。 为此,请完成以下步骤:- 在项目资源管理器视图中,右键单击HelloWorld,然后单击运行方式>运行配置 。
- 在“ 创建,管理和运行配置”窗口中,选择“ Maven Build”>“ New_configuration” ,然后单击“ 主要”选项卡(参见图8 )。
图8.运行tomcat:redeploy目标
- 单击浏览工作空间 ,然后选择应用程序> HelloWorld ,然后单击确定 。
- 在“ 目标”框中,键入
tomcat:redeploy
,然后单击“运行” 。如果重新部署目标成功执行,则“控制台”视图将显示消息“构建成功”。
现在,您可以使用HTTP客户端(例如Curl)调用HelloWorld服务,如清单3所示。
清单3.在Curl中调用HelloWorld服务
$ curl -X GET http://localhost:8080/HelloWorld/rest/world
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:ns2="http://a9.com/-/spec/opensearch/1.1/"
xmlns:ns3="http://www.w3.org/1999/xhtml">
<id>helloworld:1</id>
<updated>2010-01-06T13:26:43.924+01:00</updated>
<title type="text">Hello World!</title>
</entry>
开发REST Web服务
在本部分中,您将从头开始开发用于管理书籍资源集合的REST Web服务。 可以从下面的“ 下载”表中获得此REST服务的源代码。
开发此类服务的关键步骤是:
- 定义资源的URI,用于操纵资源的方法以及每种方法的数据格式。
- 定义代表书籍资源的Java对象,并提供Java代码或注释以编组和解组Java对象。
- 定义将URI和HTTP方法绑定到Java方法的Java服务。
- 提供抽象类
javax.ws.rs.core.Application
的具体子类。
让我们执行这些步骤。
将路径和HTTP方法绑定到Java方法
此服务支持GET
, POST
, PUT
和DELETE
HTTP方法,并将HTTP请求映射到Java方法,如下所示:
- 使用签名
createBook(@Context UriInfo, Book)
POST /books
请求映射到Java方法。 (在JAX-RS Web服务中描述了@Context
注释。)用于创建Book资源的数据格式为:POST /books HTTP/1.1 Content-Type: application/xml <book> <title> ... </title> <isbn> .... </isbn> </book>
- 将
GET /books
请求映射到Java方法getBook()
。 获取图书资源的数据格式为:GET /books HTTP/1.1 Content-Type: application/xml
- 使用签名
getBook(@PathParam("id") int)
GET /books/{id}
请求映射到Java方法。 (在JAX-RS Web服务中描述了@PathParam
注释。)使用URI模式/books/{id}
获取书籍资源的数据格式为:GET /books/{id} HTTP/1.1 Content-Type: application/xml
- 使用签名
updateBook(@PathParam("id") int, Book)
PUT /books/{id}
请求映射到Java方法。 使用URI模式/books/{id}
更新书籍资源的数据格式为:PUT /books/{id} HTTP/1.1 Content-Type: application/xml <book> <title> ... </title> <isbn> .... </isbn> </book>
- 使用签名
deleteBook(@PathParam("id") int)
DELETE /books/{id}
请求映射到Java方法。 使用URI模式/books/{id}
删除书籍资源的数据格式为:DELETE /books/{id} HTTP/1.1 Content-Type: application/xml
书籍的对象模型
用于实现Book集合的Java对象模型具有三个类:
清单4. Book类
package com.ibm.devworks.ws.rest.books;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="book")
@XmlAccessorType(XmlAccessType.FIELD)
public class Book {
@XmlAttribute(name="id")
private int id;
@XmlElement(name="title")
private String title;
@XmlElement(name="isbn")
private String ISBN;
@XmlElement(name = "link")
private Link link;
public Book() { }
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getISBN() { return ISBN; }
public void setISBN(String ISBN) { this.ISBN = ISBN; }
public Link getLink() { return link; }
public void setLink(String uri) { this.link = new Link(uri); }
}
在Book
类中,可以使用Java XML绑定体系结构(JAXB)批注来执行Java对象的编组和解组。 Apache Wink自动对具有JAXB注释的Java对象进行编组和解Unmarshaller
,包括创建执行该工作的Marshaller
和Unmarshaller
实例。
您可以使用BookList
类表示书籍对象的集合,该类将对象内部存储在ArrayList
类型的字段中,该字段带有JAXB注释,可以转换为XML格式。
清单5. BookList类
package com.ibm.devworks.ws.rest.books;
import java.util.ArrayList;
import java.util.Map;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElementRef;
@XmlRootElement(name="books")
public class BookList {
@XmlElementRef
ArrayList<Book> books;
public BookList() { }
public BookList( Map<Integer, Book> bookMap ) {
books = new ArrayList<Book>( bookMap.values() );
}
}
您可以使用Link
类在书籍对象的XML表示形式中插入链接元素(请参见清单6 )。
清单6. Link类
package com.ibm.devworks.ws.rest.books;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@XmlRootElement(name="link")
@XmlAccessorType(XmlAccessType.FIELD)
public class Link {
@XmlAttribute
String href = null;
@XmlAttribute
String rel = "self";
public Link() { }
public Link( String uri) {
this.href = uri;
}
public Link( String href, String rel) {
this.href = href;
this.rel = rel;
}
}
JAX-RS Web服务
现在,您定义将URI和HTTP方法绑定到Java方法的Java服务。 您可以将服务定义为Java接口或类。 在前一种情况下,您还定义了实现接口的类。 在该接口中,本地化JAX-RS批注并添加一个类以实现该接口。
清单7显示了BookService
Java接口。 @javax.ws.rs.Path
批注将此接口指定为JAX-RS服务。 注释的值/books
定义服务的相对根URI。 注释@javax.ws.rs.POST
, @javax.ws.rs.GET
, @javax.ws.rs.PUT
和@javax.ws.rs.DELETE
绑定HTTP POST
, GET
, PUT
和DELETE
操作紧随其后的Java方法。
清单7. BookService接口
package com.ibm.devworks.ws.rest.books;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
@Path("/books")
public interface BookService {
@POST
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public Response createBook(@Context UriInfo uriInfo, Book book);
@GET
@Produces(MediaType.APPLICATION_XML)
public BookList getBook();
@Path("{id}")
@GET
@Produces(MediaType.APPLICATION_XML)
public Book getBook(@PathParam("id") int id);
@Path("{id}")
@PUT
@Consumes(MediaType.APPLICATION_XML)
public void updateBook(@PathParam("id") int id, Book book_updated);
@Path("{id}")
@DELETE
public void deleteBook(@PathParam("id") int id);
}
您将特定的@PATH
注释附加到URI与接口的@PATH("/books")
注释所指定的URI不同的方法上。 @PATH
批注是累积性的,这意味着在另一个路径表达式之后的路径表达式将附加到前面的表达式。 因此,绑定到deleteBook
方法的路径模式是/books/{id}
。
JAX-RS提供了一种从HTTP请求中提取信息,将其转换为Java对象,并将其注入Java方法参数的机制。 这称为注射。 使用Java注释指定注入。 在BookService
界面中,插入两个注入注释:
-
@Context
批注从HTTP请求中提取URI信息,将其转换为UriInfo
对象,然后将该对象作为方法参数uriInfo
。 -
@PathParam("id")
注释与前面的@Path({"id"})
注释匹配。 该注解提取{id}
从URI图案/books/{id}
并注入入参数的值id
的的getBook
方法。
请注意, BookService
的方法将Java对象(如Book
作为参数(并返回); 这是可能的,因为这些对象是用JAXB注释的,因此Apache Wink会自动处理将它们编组和解组的工作。
清单8显示了实现BookService
的类的框架。 BookServiceImpl
是一个单例类,它使用内存映射来维护书籍对象的集合。 单例实例使用多线程处理并发请求,因此它必须是线程安全的。
清单8. BookService实现类
package com.ibm.devworks.ws.rest.books;
import javax.ws.rs.*;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@Path("/books")
public class BookServiceImpl implements BookService {
private static BookServiceImpl instance = null;
private BookServiceImpl() { }
public synchronized static BookServiceImpl getInstance() {
if(instance == null) {
instance = new BookServiceImpl();
}
return instance;
}
private Map <Integer, Book> bookMap =
new ConcurrentHashMap <Integer, Book>();
private AtomicInteger seqNumber = new AtomicInteger();
public Response createBook(@Context UriInfo uriInfo, Book book)
throws WebApplicationException {
...
}
public BookList getBook() {
...
}
public Book getBook(@PathParam("id") int id)
throws WebApplicationException {
...
}
public void updateBook(@PathParam("id") int id, Book book_updated)
throws WebApplicationException {
...
}
public void deleteBook(@PathParam("id") int id)
throws WebApplicationException {
...
}
}
您将书籍对象的集合存储在地图中。 要提供对地图的线程安全访问,请使用ConcurrentHashMap
。 要生成唯一的书ID,请使用AtomicInteger
,以确保增量操作是原子的,因此是线程安全的。
子类化Application抽象类
JAX-RS Web应用程序包含一组资源(REST Web服务)。 这些资源作为JAX-RS抽象类javax.ws.rs.core.Application
子类公开。 清单9中所示的BookWebApp
类扩展了Application
类。
清单9. javax.ws.rs.core.Application的具体子类
package com.ibm.devworks.ws.rest.books;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class BookWebApp extends Application {
private Set<Object> svc_singletons = new HashSet<Object>();
private Set<Class<?>> svc_classes = new HashSet<Class<?>>();
public BookWebApp() {
svc_singletons.add(BookServiceImpl.getInstance());
}
@Override
public Set<Object> getSingletons() {
return svc_singletons;
}
@Override
public Set<Class<?>> getClasses() {
return svc_classes;
}
}
BookWebApp
的构造BookWebApp
获取图书服务实现对象的单例实例。 getSingletons
方法返回一个集合,该集合的唯一元素是此单例。 服务请求后,JAX-RS不会处理单例。
构建和部署REST Web服务
您使用Eclipse创建一个动态Web项目。 该项目包含上一节中描述的Java类以及其他资源,例如Web应用程序部署描述符和所需的JAR文件。
注意:创建Eclipse动态Web项目的替代方法是从诸如maven-archetype-webapp
或webapp-jee5
类的原型创建Maven项目。 ( 原型是Maven项目模板。)但是,在当前版本的Maven中,生成Eclipse使用的项目元数据存在一些故障:要在IDE中启用自动代码构建,必须手动修改某些Eclipse项目文件。 因此,本文使用Eclipse动态Web项目。
Web服务的Eclipse项目
Eclipse动态Web项目支持开发在servlet容器中运行的Web应用程序,因此它是用于开发Apache Wink服务的很好的项目模板。 要为Book REST服务创建一个动态Web项目,请完成以下步骤:
- 在Eclipse中,单击文件>新建>动态Web项目 。
- 在“动态Web项目向导”中,在“ 项目名称”框中键入“
Books
”。 - 通过单击“ 目标运行时”框旁边的“ 新建”来设置Tomcat运行时 。
- 在“ 新建服务器运行时环境”向导页面上,单击Apache> Apache Tomcat v6.0 ,然后单击下一步 。
- 在“ Tomcat服务器”向导页上,单击“ 浏览” ,然后导航到“ 先决条件”部分中定义的CATALINA_HOME目录。
- 单击“ 确定” ,然后单击“ 完成” 。
- 在“ 动态Web项目”页面上,单击“ 完成” 。
将上一节中描述的Java类添加到您创建的Books项目中。 为此,请完成以下步骤:
- 在项目资源管理器视图中,打开“书籍”文件夹。 右键单击Java Resources:src ,然后单击新建>包 。
- 在“ Java软件包”窗口的“ 名称”框中,键入软件包的名称
com.ibm.devworks.ws.rest.books
,然后单击“ 完成” 。 - 将Java类添加到
com.ibm.devworks.ws.rest.books
包中:- 在“项目资源管理器”视图中,右键单击该包,然后单击“ 新建”>“类” 。
- 在名称框中,输入类的名称(例如
Book
forBook.java
),然后单击Finish 。 - 使用Eclipse Java编辑器创建类。
接下来,将构建和运行Apache Wink服务所需的JAR文件添加到项目中。 创建应用程序项目时,Maven将JAR文件下载到本地存储库。 本地存储库位于Windows中的%HOMEPATH%\。m2 \ repository或Linux中的$ HOME / .m2 / repository中。
要将JAR文件添加到项目,请完成以下步骤:
- 在项目资源管理器视图中,导航到“书籍/ Web内容/ WEB-INF”。
- 右键单击lib ,然后单击导入>常规>文件系统 ,然后单击下一步 。
- 在“ 文件系统”窗口中,通过导航到包含JAR文件的目录,从本地Maven存储库(当您导入应用程序Apache Wink模块时由m2eclipse填充)导入JAR文件jsr311-api-1.0.jar。 好吧 在“ 文件系统”窗口中,选择JAR文件,然后单击“ 完成” 。
- 对JAR文件wink-server-1.0-incubating.jar,wink-common-1.0-incubating.jar,slf4j-api-1.5.8.jar和slf4j-simple-1.5.8.jar重复步骤2和3。
导入所有库之后,lib目录将包含图9所示的JAR文件。
图9. Apache Wink服务所需的库
您还可以通过从下面的“ 下载”部分中提供的代码示例中导入项目来为Book服务创建Eclipse项目。 为此,请下载并解压缩文件。 然后,在Eclipse中,单击文件>导入>现有项目到工作区 。 在“导入项目向导”中,单击“ 浏览” ,导航到“书籍”文件夹,单击“ 确定” ,然后单击“ 完成” 。
将服务部署到Tomcat中
在清单10所示的部署描述符文件web.xml中,您将具有相对根路径/ *的URI映射到Wink servlet org.apache.wink.server.internal.servlet.RestServlet
。 将RestServlet
作为init-param
传递给Book服务提供的Application
子类的名称。
清单10. BookService部署描述符web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID"
version="2.5">
<display-name>Book Web Application</display-name>
<servlet>
<servlet-name>restSdkService</servlet-name>
<servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.ibm.devworks.ws.rest.books.BookWebApp</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>restSdkService</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
设置部署描述符后,可以将Books服务部署到Tomcat。 为了进行测试,请在Eclipse管理的Tomcat实例中部署和运行Book服务。 为此,请完成以下步骤:
- 在“项目资源管理器”视图中,右键单击“ 书籍” ,然后单击“运行方式”>“在服务器上运行” 。
- 在“在服务器上运行”窗口中,单击“ 完成” ,这会将Books服务部署到创建Books项目时配置的Tomcat运行时,并启动Tomcat。
完成测试后,将Books服务打包在WAR文件中,以部署到生产环境。 为此,在Project Explorer视图中,右键单击Books ,然后单击Export> WAR file 。 在“ WAR导出向导”中,单击“ 浏览” ,选择要在其中创建WAR文件的文件夹,然后单击“ 保存并完成” 。
调用REST Web服务
您可以使用支持HTTP操作GET
, POST
, PUT
和DELETE
的HTTP客户端来调用Books服务。 清单11显示了如何使用Curl调用服务。 首先,获得所有书籍的表示形式(最初没有书籍); 然后,使用jaxrs.xml和rest.xml表示法创建两本书。 最后,获得所有书籍和id=2
的书籍的表示形式。
清单11.调用Book服务
$ curl -X GET http://localhost:8080/Books/books
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<books/>
$ more Books\xml\jaxrs.xml
<?xml version="1.0" encoding="UTF-8"?>
<book>
<titleRESTful Java with JAX-RS</title>
<isbn>978-0-596-15804-0</isbn>
</book>
$ more Books\xml\rest.xml
<?xml version="1.0" encoding="UTF-8"?>
<book>
<title>RESTful Web Services</title>
<isbn>978-0-596-52926-0</isbn>
</book>
$ curl -H "Content-Type: application/xml" -T Books\xml\jaxrs.xml \
-X POST http://localhost:8080/Books/books
$ curl -H "Content-Type: application/xml" -T Books\xml\rest.xml \
-X POST http://localhost:8080/Books/books
$ curl -X GET http://localhost:8080/Books/books
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<books>
<book id="2">
<title>RESTful Web Services</title>
<isbn>978-0-596-52926-0</isbn>
<link rel="self" href="http://localhost:8080/Books/books/2"/>
</book>
<book id="1">
<title>RESTful Java with JAX-RS</title>
<isbn>978-0-596-15804-0</isbn>
<link rel="self" href="http://localhost:8080/Books/books/1"/>
</book>
</books>
$ curl -X GET http://localhost:8080/Books/books/2
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book id="2">
<title>RESTful Web Services</title>
<isbn>978-0-596-52926-0</isbn>
<link rel="self" href="http://localhost:8080/Books/books/2"/>
</book>
结论
本文展示了一系列技术如何可以协同工作,以实现Apache Wink REST Web服务的开发,构建和部署。 Java注释的功能简化了开发过程。
REST Web服务使应用程序可以交换链接的数据。 Tim Berners-Lee爵士曾预测,链接数据将改变Web。 Bill Burke在他的书《 使用JAX-RS的RESTful Java》中指出,通过将服务交互的复杂性限制在数据表示中,REST Web服务将服务的可组合性和重用性提高到一个新的水平。
本文仅涉及开发Apache Wink服务的内容。 Apache Wink的其他重要功能包括链接生成器,自定义消息正文读取器和用于不受支持的数据格式的写入器。 要了解有关Apache Wink框架的更多信息,请确保查看Apache Wink中包含的其他示例。
翻译自: https://www.ibm.com/developerworks/web/library/wa-useapachewink/index.html
如何使用wink框架