- 浏览: 371445 次
- 性别:
- 来自: 阿里巴巴
-
文章分类
- 全部博客 (207)
- Maven (5)
- Cassandra (2)
- Hadoop (3)
- LDAP (2)
- SOA (7)
- 认证、加密、安全 (6)
- 搜索引擎相关技术 (3)
- REST (7)
- 数据库 (11)
- Java 基础相关 (38)
- UML (1)
- Java NIO 框架 (3)
- javassist (1)
- Bean容器 (4)
- 网络编程 (1)
- NoSQL (4)
- XML、Json (1)
- JS (2)
- Google (6)
- Warp-MVC (2)
- 持久层 (2)
- sitebricks (1)
- MVC (6)
- CSS (2)
- JPA (2)
- RDBMS (5)
- cache (4)
- tomcat (1)
- 其它 (3)
- eclipse (1)
- bigpipe (1)
- RDBMS MySQL (1)
- MySQL (2)
- ant (1)
- 前端 (2)
- Groovy (1)
- linux (3)
- Scala (1)
- zookeeper (1)
- redis (2)
- 测试 (1)
- 监控 (1)
- mac (3)
- 区块链 (3)
- 工具 (1)
最新评论
-
masuweng:
好好好,辛苦了!!
Spring Data JPA 简单介绍 -
masuweng:
Spring Data JPA 简单介绍 -
zhangjianxinjava:
您好,大神本人小白一个最近在研究不知道可否 通过邮箱进行交流, ...
JAVA Metrics度量工具 - Metrics Core -
xzs603:
http://zhengdl126.iteye.com/blo ...
数据库水平切分的实现原理解析---分库,分表,主从,集群,负载均衡器 -
JavaStart:
运行mysql2redis 的install.sh 文件为何提 ...
mysql到redis的复制
http://www.ibm.com/developerworks/cn/web/wa-useapachewink/
Apache Wink 是一个促进创建和使用 REST Web 服务的 Apache 孵化器项目。通过 REST Web 服务,客户机和服务之间的交互局限于一组预定义的操作,客户机和服务器之间的交互的复杂性限制为客户机和服务之间交换的资源表示。这种方法支持构建可互操 作、可伸缩、可靠的、基于 REST 的分布式超媒体系统。
常用缩略词
- API: 应用程序编程接口
- HTTP: 超文本传输协议
- IDE: 集成开发环境
- JSON: JavaScript 对象符号
- REST: 具象状态传输
- URI: 统一资源标识符
- XML: 可扩展标记语言
本文介绍如何使用 Apache Wink、Eclipse IDE 以及 Maven 项目管理工具开发、部署和运行 RESTful Web 服务。
设计 Web 服务的 REST 方法将客户机和服务之间的交互限制到一组创建、读取、更新和删除(CRUD)操作。这些操作直接映射到 HTTP 方法 — 具体而言,映射到
POST
、GET
、
PUT
和 DELETE
。尽管 RESTful 样式没有绑定到 HTTP 协议,本文假设 HTTP 用于客户机和服务之间的通信。
REST Web 服务在资源上执行 CRUD 操作。客户机使用资源状态的 REST 服务表示进行交换。这些表示使用的数据格式在 HTTP 请求或响应的头部中指定 — XML 和 JSON 是广泛使用的格式。数据格式可能在不同操作之间发生变化;例如,创建资源的数据格式与用于读取资源的数据格式不同。REST 服务保持资源的状态,但 — 与 servlets 不同的是 — 不保持客户机会话信息。
REST 方法支持构建可互操作、可伸缩和可靠的基于 REST 的分布式系统。例如,GET
、POST
和 DELETE
方法是等幂的,即多次执行它们与执行一次的结果相同。由于 GET
操作不会更改资源的状态,因此 GET
请求的结果可以缓存起来以加快 “请求-响应” 循环。
JAX-RS 为基于 HTTP 协议的 RESTful Java Web 服务定义了一个 API。JAX-RS 实现包括 Apache Wink、Sun Jersey 和 JBoss RESTEasy。 本文将使用 Apache Wink。
JAX-RS 利用 Java 注释的威力,使用注释来执行诸如以下的操作:
- 将 HTTP 方法和 URIs 绑定到 Java 类的方法
- 将来自 URI 或 HTTP 头部的元素作为方法参数注入
- 在 HTTP 消息体和 Java 类型之间来回转换
- 将 URI 模式绑定到 Java 类和方法 —
@Path
注释 - 将 HTTP 操作绑定到 Java 方法 —
@GET
、@POST
、@PUT
和@DELETE
注释
JAX-RS 还提供了一个框架来构建新功能。例如,对于自定义数据格式,程序员可以开发消息阅读器并将 Java 对象编组到 HTTP 消息并从 HTTP 消息解组它们。
在本文中,您将使用 Eclipse 和 Maven 下载 Apache Wink,运行 Apache Wink 中包含的 HelloWorld 示例,然后将您自己的 REST Web 服务创建为一个 Eclipse 项目。
在这个小节中,您将使用 Eclipse 以及 Maven Integration for Eclipse(称为 m2eclipse)和 Subclipse 插件来安装 Apache Wink。(M2eclipse 提供从 Eclipse 对 Maven 的访问;Subclipse 提供对 Subversion 资源库的访问。)您还可以将 Eclipse 用作一个平台,从这个平台构建并运行 Web 服务。
在获取 Apache Wink 之前,要先下载并安装以下软件包(参见 参考资料 获取下载 URLs):
- Java Software Development Kit (JDK) version 6。 设置 JAVA_HOME 环境变量并添加到路径 %JAVA_HOME%\bin(在 Windows® 中)或 $JAVA_HOME/bin(在 Linux® 中)。
- Apache Tomcat version 6.0。 设置 CATALINA_HOME 环境变量以指向安装目录。
- Eclipse IDE for Java™ Platform, Enterprise Edition (Java EE) developers。 本文撰写之时的当前版本为 Eclipse Galileo。
要使用 Eclipse 管理具有 Maven 感知的项目,要安装 Eclipse 插件 Subclipse 和 m2eclipse。要安装 Subclipse 插件,执行以下步骤:
- 启动 Eclipse。
- 单击菜单栏中的 Help ,然后选择 Install new software 。
- 在 Available Software 窗口中,单击 Add 。
- 在 Add Site
窗口中,输入:
Name: Subclipse Location: http://subclipse.tigris.org/update_1.6.x/
然后单击 OK 。
- 在 Available Software
窗口中,选择 Subclipse
下的 Subclipse
(Required)
和 SVNKit Client Adapter (Not required)
复选框(如 图 1
所示),然后单击 Next
。
图 1. 安装 Subclipse 插件
- 在 Install Details 窗口中,单击 Next 。
- 在 Review Licenses 窗口中,检查许可,接受许可协议条款,然后单击 Finish 。
- 单击 Yes 重新启动 Eclipse。
m2eclipse 插件的安装步骤与安装 Subclipse 插件类似,但有以下几点例外:
- 在 Add Site
窗口中输入:
Name: Maven Integration for Eclipse Location: http://m2eclipse.sonatype.org/update/
然后单击 OK 。
- 在 Available Software
窗口中,选择 Maven Integration
for Eclipse (Required)
和 Maven SCM handler for Subclipse
(Optional)
复选框(如 图 2
所示),然后单击 Next
。
图 2. 安装 m2eclipse 插件
现在,您可以使用 Eclipse 从资源库检查 Apache Wink 示例,将必要的 Java 归档(JAR)文件(包括 Apache Wink JAR 文件)下载到一个本地资源库,构建并运行 Apache Wink HelloWorld 示例。为此,执行以下步骤:
- 在 Eclipse 中,选择 File > Import 启动 Import Wizard。
- 在 Select
向导页面的 Select and import source
文本框中输入
maven
。 - 在 Maven 下,选择 Materialize Maven Projects 并单击 Next 。
- 在 Select Maven artifacts 向导页面上单击 Add 。
- 在 Add Dependency
页面上的 Enter groupId, artifactId
文本框中输入
org.apache.wink.example
。
注意: Artifact(工件) 是一个用于 Maven 的术语,指的是设置了版本并存储在资源库中的软件包的层级结构。 - 在 Search Results
区域中,选择 org.apache.wink.example apps
(如 图 3
所示)并单击 OK
。
图 3. org.apache.wink.example 组中的应用程序工件
- 在 Select Maven artifacts 向导页面上,单击 Next ,然后单击 Finish 。
- 在 Maven Projects 向导页面上,只选择 /pom.xml 复选框,然后单击 Finish 。
Maven 处理一个工件的所有依赖项的方式是从远程资源库下载它们并构建一个本地资源库。Maven 的优势之一是能够处理临时依赖项;因此,在 Maven Project Object Model (POM) 文件中,只需声明工件的传递依赖项(transitive dependencies),Maven 将为您处理高阶依赖项(higher-order dependencies)。
步骤 8 完成后,将创建一个 Eclipse 项目,它包含 Apache Wink 示例的 apps
模块中的代码。在 Eclipse 的 Project Explorer 中浏览项目文件。
我们来检查一下 apps
模块中的 HelloWorld
Java 类。在 Project Explorer 视图中,单击 apps > HelloWorld > src > main
,然后打开文件 HelloWorld.java,该文件的结构如 清单 1
所示。
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
所示。
注意,URI 模式 /rest/*
被绑定到
restSdkService
servlet,这个 servlet 的 context path 是 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>
元素所示。RestServlet
类使用初始参数 applicationConfigLocation
传递 HelloWorld
类的名称,这个初始参数反过来指向位于 HelloWorld/src/main/webapp/WEB-INF 文件夹中的 web.xml 旁边的 application 文件。这个 application 文件只有一行,即
HelloWorld
资源的限定名:
org.apache.wink.example.helloworld.HelloWorld |
RestServlet
servlet 可以在 “无 JAX-RS 感知” 的
servlet 容器中运行,从而支持将 JAX-RS 服务轻松部署到 “无 JAX-RS 感知” 的容器中。
我们现在开始构建 HelloWorld 服务,然后将其部署到 Tomcat 6.0 servlet 容器中并运行。
在 Eclipse 中,可以使用 m2eclipse 插件来构建、部署和运行 HelloWorld。首先,编译源代码并为 HelloWorld 服务构建 Web 归档 (WAR) 文件。要构建这个服务,指示 m2eclipse 执行安装 生命周期阶段。(执行一个 Maven 生命周期阶段将触发项目生命周期中的此前阶段的执行。)要执行安装阶段,在 Project Explorer 视图中右键单击 HelloWorld,然后单击 Run As > Maven install ,如 图 5 所示。
Maven (从中央资源库 http://repo1.maven.org/maven2 或从镜像资源库)下载所有依赖项,并在 Windows® 中的 %HOMEPATH%\.m2\repository 或 Linux® 中的 $HOME/.m2/repository 下构建本地资源库。Maven 执行的动作记录在 Eclipse 窗口的 Console 视图中。
如果安装阶段成功结束,那么 WAR 文件 HelloWorld.war 就构建在目标目录下并部署到本地资源库中,Console 视图将显示消息 “Build successful”。
您将使用 Maven 的 Tomcat 插件。(与 Eclipse 一样,Maven 通过插件提供大量功能。)您必须将 Tomcat 插件的位置告知 Maven,方法是指定插件的 groupId
和 artifactId
,如 图 6
所示(pom.xml 中的 45-46 行)。
您还需要告知 Maven 用于访问 Tomcat manager 应用程序的用户名和密码。Maven 使用 manager 应用程序来指导 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 插件的 redeploy 目标。(一个 Maven 目标(goal) 被自身执行,这与生命周期阶段不同,后者的执行由生命周期中的此前阶段自动推进。)要执行 redeploy 目标,执行以下步骤:
- 在 Tomcat 配置文件 conf/tomcat-users.xml(位于 CATALINA_HOME 下)中插入身份验证信息(如 图 7
所示),但要使用一个密码,而不是 admin
。
图 7. Tomcat 身份验证配置
- 通过运行以下命令启动 Tomcat:
In Windows: %CATALINA_HOME%\bin\catalina.bat start In Linux: $CATALINA_HOME/bin/catalina.sh start
- 执行
maven tomcat:redeploy
,这条命令使用 Tomcat manager 应用程序将 HelloWorld.war 部署到 Tomcat。为此,执行以下步骤:- 在 Project Explorer 视图中,右键单击 HelloWorld,然后单击 Run As > Run configurations 。
- 在 Create, manage, and run configurations
窗口中,选择 Maven Build > New_configuration
,然后单击 Main
选项卡(参见 图 8
)。
图 8. 运行 tomcat:redeploy 目标
- 单击 Browse workspace ,然后选择 apps > HelloWorld ,然后单击 OK 。
- 在 Goals
文本框中,输入
tomcat:redeploy
,然后单击 Run 。如果 redeploy 目标成功执行,Console 视图将显示消息 “Build successful”。
现在,您可以使用一个 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 服务的源代码可以从下面的 下载 表中获取。
开发这样一个服务的关键步骤是:
- 定义资源的 URIs,用于操作资源的方法,以及每个方法的数据格式。
- 定义表示图书资源的 Java 对象,提供 Java 代码或注释来编组和解组 Java 对象。
- 定义将 URIs 和 HTTP 方法绑定到 Java 方法的 Java 服务。
- 提供
javax.ws.rs.core.Application
抽象类的一个具体子类。
下面我们就执行这些步骤。
这个服务支持 GET
, POST
、PUT
和 DELETE
HTTP
方法,并按如下方式将 HTTP 请求映射到 Java 方法:
- 将
POST /books
请求映射到带有createBook(@Context UriInfo, Book)
签名的 Java 方法。(@Context
注释将在 JAX-RS Web 服务 小节中介绍。)用于创建一个图书资源的数据格式为: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
- 将
GET /books/{id}
请求映射到带有getBook(@PathParam("id") int)
签名的 Java 方法。(@PathParam
注释将在 JAX-RS Web 服务 小节中介绍。)用于获取带有 URI 模式/books/{id}
的图书资源的数据格式为:GET /books/{id} HTTP/1.1 Content-Type: application/xml
- 将
PUT /books/{id}
请求映射到带有updateBook(@PathParam("id") int, Book)
签名的 Java 方法。用于更新带有 URI 模式/books/{id}
的图书资源的数据格式为:PUT /books/{id} HTTP/1.1 Content-Type: application/xml <book> <title> ... </title> <isbn> .... </isbn> </book>
- 将
DELETE /books/{id}
请求映射到带有deleteBook(@PathParam("id") int)
签名的 Java 方法。用于删除带有 URI 模式/books/{id}
的图书资源的数据格式为:DELETE /books/{id} HTTP/1.1 Content-Type: application/xml
用于实现这个图书集合的 Java 对象模型有 3 个类:
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 Architecture for XML Binding
(JAXB) 注释来执行 Java 对象的编组和解组。Apache
Wink 自动编组和解组带有 JAXB 注释的 Java 对象,包括创建执行编组和解组工作的 Marshaller
和
Unmarshaller
实例。
您将使用 BookList
类来表示图书对象的集合,BookList
类将这些对象以内部存储方式存储在 ArrayList
类型的一个字段中,ArrayList
带有 JAXB 注释,以便转换为 XML 格式。
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
)。
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; } } |
现在,您已经定义了将 URIs 和 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 方法。
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); } |
对于其 URI 与接口的 @PATH("/books")
注释指定的值不同的方法,您将一个特定的 @PATH
注释附加到那些方法。@PATH
注释是可以累积的,即,一个路径表达式后面的另一个路径表达式将附加到前面的表达式。因此,绑定到 deleteBook
方法的路径模式为 /books/{id}
。
JAX-RS 提供了一种机制,用于从一个 HTTP 请求提取信息,将信息赋予一个 Java 对象,然后将该对象注入一个 Java 方法参数。这种机制称为注入(injection)。注入使用 Java 注释指定。在 BookService
接口中,您将插入两个注入注释:
-
@Context
注释从 HTTP 请求提取 URI 信息,将其转换为UriInfo
对象,然后将这个对象作为方法参数uriInfo
注入。 -
@PathParam("id")
注释匹配前面的@Path({"id"})
注释。这个注释从 URI 模式/books/{id}
提取{id}
,并将其注入getBook
方法的id
参数的值。
注意,BookService
的方法将 Java 对象(比如 Book
)接收为参数并返回 Java 对象;这是可能的,因为这些对象带有 JAXB 注释,因此 Apache Wink 能够对它们进行自动编组和解组。
清单 8
展示了实现 BookService
的类的结构。BookServiceImpl
是一个 singleton 类,使用一个内存映射图(in-memory map)来维护图书对象集合。singleton 实例使用多线程服务并发请求,因此它必须是线程安全的(thread-safe)。
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
。要生成惟一的图书 IDs,您将使用一个 AtomicInteger
,它能确保增量操作是原子级的(atomic),从而确保线程安全。
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
的构造函数获取这个图书服务实现对象的 singleton 实例。getSingletons
方法返回一个组,其惟一元素就是这个 singleton。JAX-RS 在服务一个请求后并不删除这个 singleton。
您将使用 Eclipse 来创建一个动态 Web 项目,这个项目包含上一小节介绍过的 Java 类和其他资源,比如 Web 应用程序部署描述符和必要的 JAR 文件。
注意:
创建一个 Eclipse 动态 Web 项目的另一种方法是从一个 archetype(比如 maven-archetype-webapp
或 webapp-jee5
)创建一个 Maven 项目(archetype 是一个 Maven
项目模板)。但是,在 Maven 当前版本中,生成 Eclipse 使用的项目元数据时会出现一些问题:要支持 IDE
中的自动代码构建,必须手动修改一些 Eclipse 项目文件。因此,本文使用 Eclipse 动态 Web 项目。
Eclipse 动态 Web 项目支持开发在一个 servlet 容器中运行的 Web 应用程序,因此它是用于开发 Apache Wink 服务的一个不错的项目模板。要为这个图书 REST 服务创建一个动态 Web 项目,执行以下步骤:
- 在 Eclipse 中,单击 File > New > Dynamic Web Project 。
- 在 Dynamic Web Project Wizard 中,在 Project name
文本框中输入
Books
。 - 单击 Target runtime 方框旁边的 New 创建一个 Tomcat 运行时。
- 在 New Server Runtime Environment 向导页面上,单击 Apache > Apache Tomcat v6.0 ,然后单击 Next 。
- 在 Tomcat Server 向导页面上,单击 Browse ,然后导航到 先决条件 小节中定义的 CATALINA_HOME 目录。
- 单击 OK ,然后单击 Finish 。
- 在 Dynamic Web Project 页面上,单击 Finish 。
将上一小节中介绍的 Java 类添加到刚才创建的 Books 项目中。为此,执行以下步骤:
- 在 Project Explorer 视图中,打开 Books 文件夹。右键单击 Java Resources:src ,然后单击 New > Package 。
- 在 Java Package
窗口中的 Name
文本框中,输入包名称 —
com.ibm.devworks.ws.rest.books
— 并单击 Finish 。 - 将 Java 类添加到
com.ibm.devworks.ws.rest.books
包:- 在 Project Explorer 视图中,右键单击上述包,然后单击 New > Class 。
- 在 Name
文本框中,输入类名称(比如为
Book.java
输入Book
),然后单击 Finish 。 - 使用 Eclipse Java 编辑器来创建类。
然后,向项目添加构建和运行一个 Apache Wink 服务所需的 JAR 文件。当您创建这个应用程序项目时,Maven 将 JAR 文件下载到本地资源库,本地资源库驻留在 %HOMEPATH%\.m2\repository(Windows)或 $HOME/.m2/repository(Linux)中。
要将 JAR 文件添加到这个项目,执行以下步骤:
- 在 Project Explorer 视图中,导航到 Books/Web Content/WEB-INF。
- 右键单击 lib ,然后单击 Import > General > File System ,然后单击 Next 。
- 在 File System 窗口中,从 Maven 资源库(已在导入应用程序 Apache Wink 模块时由 m2eclipse 填充)导入 JAR 文件 jsr311-api-1.0.jar,方法是导航到包含这个 JAR 文件的目录,然后单击 OK 。在 File System 窗口中,选中这个 JAR 文件,然后单击 Finish 。
- 重复步骤 2 到步骤 3,分别导入 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。
所有库都导入后,lib 目录将包含如 图 9 所示的 JAR 文件。
您还可以通过从下面的 下载 部分中提供的代码样例中导入 Book 服务来创建这个 Eclipse 项目。为此,下载并解压文件,然后在 Eclipse 中单击 File > Import > Existing Project Into Workspace 。在 Import Projects Wizard 中,单击 Browse , 导航到 Books 文件夹,单击 OK ,然后单击 Finish 。
在部署描述符文件 web.xml(如 清单 10
所示)中,您将带有相对根路径 /* 的 URIs 映射到 Wink servlet
org.apache.wink.server.internal.servlet.RestServlet
。RestServlet
被传递为 init-param
,这是 Books 服务提供的 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 了。为了进行测试,将这个 Books 服务部署到一个由 Eclipse 托管的 Tomcat 实例中并运行。为此,执行以下步骤:
- 在 Project Explorer 视图中,右键单击 Books ,然后单击 Run As > Run on Server 。
- 在 Run on Server 窗口中,单击 Finish ,这将把这个 Books 服务部署到创建这个 Books 项目时配置的 Tomcat 运行时中并启动 Tomcat。
测试完成后,您将这个 Books 服务打包到一个 WAR 文件中,以备部署到生产环境中。为此,在 Project Explorer 视图中,右键单击 Books ,然后单击 Export > WAR file 。在 WAR Export Wizard 中,单击 Browse ,选择创建 WAR 文件的文件夹,然后单击 Save 和 Finish 。
可以使用一个支持 HTTP 操作 GET
、POST
、PUT
和 DELETE
的 HTTP 客户机来调用这个 Books 服务。
清单 11
展示了如何使用 Curl 来调用这个服务。首先,您将得到所有图书的表示(最初没有图书);然后,您使用 jaxrs.xml 和 rest.xml 两个表示来创建两本图书;最后,您得到所有图书的表示和 id=2
的图书的表示。
$ 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 在他撰写的图书 RESTful Java with JAX-RS 中指出,通过将服务交互的复杂性限制为数据表示,REST Web 服务将服务组合性和重用提高到一个新的水平。
本文仅仅涉及 Apache Wink 服务开发的皮毛,Apache Wink 的其他重要特性包括链接构建器、自定义消息体阅读器以及针对不受支持的数据格式的编写器。要深入了解 Apache Wink 框架,一定要看一看 Apache Wink 中包含的其他示例。
发表评论
-
REST
2011-12-28 17:21 1146Rest初探 一种思维方式 ... -
用Restlet创建面向资源的服务
2011-09-22 22:17 1258http://www.infoq.com/cn/art ... -
JRest4Guice
2011-09-22 19:42 1479项目地址: http://code.google.com/p/ ... -
更简单,更强大的JAX-WS
2011-04-07 22:31 1430JAX-WS2.0的来历------------------- ... -
Java REST框架一览
2010-08-29 21:05 1104目前宣称支持REST的Java ... -
利用Restlet开发的研究--Restlet的背景
2010-08-22 22:16 14441.1、Servlet的问题 1)没有对协议与应用之间的关系 ...
相关推荐
总结起来,"apache-wink-1.3.0-src.tar.gz"是一个包含Apache Wink 1.3.0版本源代码的压缩包,适合对RESTful Web服务感兴趣的开发者,他们可以借此深入了解Wink的内部机制,进行定制开发,并与其他Java技术结合使用,...
5. **开发和调试**:使用IDE(如Eclipse、IntelliJ IDEA)导入项目,然后就可以开始编写自己的RESTful服务或客户端代码,并进行调试。 **标签"jar"的关联:** Apache Wink的源代码中包含了许多.jar文件,它们是编译...
1、文件内容:sblim-gather-provider-2.2.8-9.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/sblim-gather-provider-2.2.8-9.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
本图书进销存管理系统管理员功能有个人中心,用户管理,图书类型管理,进货订单管理,商品退货管理,批销订单管理,图书信息管理,客户信息管理,供应商管理,库存分析管理,收入金额管理,应收金额管理,我的收藏管理。 用户功能有个人中心,图书类型管理,进货订单管理,商品退货管理,批销订单管理,图书信息管理,客户信息管理,供应商管理,库存分析管理,收入金额管理,应收金额管理。因而具有一定的实用性。 本站是一个B/S模式系统,采用Spring Boot框架,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得图书进销存管理系统管理工作系统化、规范化。本系统的使用使管理人员从繁重的工作中解脱出来,实现无纸化办公,能够有效的提高图书进销存管理系统管理效率。 关键词:图书进销存管理系统;Spring Boot框架;MYSQL数据库
2024中国在人工智能领域的创新能力如何研究报告.pdf
人脸识别项目实战
人脸识别项目实战
人脸识别项目实战
内容概要:本文档详细介绍了基于CEEMDAN(完全自适应噪声集合经验模态分解)的方法实现时间序列信号分解的具体项目。文中涵盖项目背景介绍、主要目标、面临的挑战及解决方案、技术创新点、应用领域等多方面内容。项目通过多阶段流程(数据准备、模型设计与构建、性能评估、UI设计),并融入多项关键技术手段(自适应噪声引入、并行计算、机器学习优化等)以提高非线性非平稳信号的分析质量。同时,该文档包含详细的模型架构描述和丰富的代码样例(Python代码),有助于开发者直接参考与复用。 适合人群:具有时间序列分析基础的科研工作者、高校教师与研究生,从事信号处理工作的工程技术人员,或致力于数据科学研究的从业人员。 使用场景及目标:此项目可供那些面临时间序列数据中噪声问题的人群使用,尤其适用于需从含有随机噪音的真实世界信号里提取有意义成分的研究者。具体场景包括但不限于金融市场趋势预测、设备故障预警、医疗健康监控以及环境质量变动跟踪等,旨在提供一种高效的信号分离和分析工具,辅助专业人士进行精准判断和支持决策。 其他说明:本文档不仅限于理论讲解和技术演示,更着眼于实际工程项目落地应用,强调软硬件资源配置、系统稳定性测试等方面的细节考量。通过完善的代码实现说明以及GUI界面设计指南,使读者能够全面理解整个项目的开发流程,同时也鼓励后续研究者基于已有成果继续创新拓展,探索更多的改进空间与发展机遇。此外,针对未来可能遇到的各种情况,提出了诸如模型自我调整、多模态数据融合等发展方向,为长期发展提供了思路指导。
监护人,小孩和玩具数据集 4647张原始图片 监护人 食物 孩子 玩具 精确率可达85.4% pasical voc xml格式
人脸识别项目实战
人脸识别项目实战
在智慧园区建设的浪潮中,一个集高效、安全、便捷于一体的综合解决方案正逐步成为现代园区管理的标配。这一方案旨在解决传统园区面临的智能化水平低、信息孤岛、管理手段落后等痛点,通过信息化平台与智能硬件的深度融合,为园区带来前所未有的变革。 首先,智慧园区综合解决方案以提升园区整体智能化水平为核心,打破了信息孤岛现象。通过构建统一的智能运营中心(IOC),采用1+N模式,即一个智能运营中心集成多个应用系统,实现了园区内各系统的互联互通与数据共享。IOC运营中心如同园区的“智慧大脑”,利用大数据可视化技术,将园区安防、机电设备运行、车辆通行、人员流动、能源能耗等关键信息实时呈现在拼接巨屏上,管理者可直观掌握园区运行状态,实现科学决策。这种“万物互联”的能力不仅消除了系统间的壁垒,还大幅提升了管理效率,让园区管理更加精细化、智能化。 更令人兴奋的是,该方案融入了诸多前沿科技,让智慧园区充满了未来感。例如,利用AI视频分析技术,智慧园区实现了对人脸、车辆、行为的智能识别与追踪,不仅极大提升了安防水平,还能为园区提供精准的人流分析、车辆管理等增值服务。同时,无人机巡查、巡逻机器人等智能设备的加入,让园区安全无死角,管理更轻松。特别是巡逻机器人,不仅能进行360度地面全天候巡检,还能自主绕障、充电,甚至具备火灾预警、空气质量检测等环境感知能力,成为了园区管理的得力助手。此外,通过构建高精度数字孪生系统,将园区现实场景与数字世界完美融合,管理者可借助VR/AR技术进行远程巡检、设备维护等操作,仿佛置身于一个虚拟与现实交织的智慧世界。 最值得关注的是,智慧园区综合解决方案还带来了显著的经济与社会效益。通过优化园区管理流程,实现降本增效。例如,智能库存管理、及时响应采购需求等举措,大幅减少了库存积压与浪费;而设备自动化与远程监控则降低了维修与人力成本。同时,借助大数据分析技术,园区可精准把握产业趋势,优化招商策略,提高入驻企业满意度与营收水平。此外,智慧园区的低碳节能设计,通过能源分析与精细化管理,实现了能耗的显著降低,为园区可持续发展奠定了坚实基础。总之,这一综合解决方案不仅让园区管理变得更加智慧、高效,更为入驻企业与员工带来了更加舒适、便捷的工作与生活环境,是未来园区建设的必然趋势。
本届年会的主题是“青春梦想创新创业”。通过学术论文报告、创新创业项目展示、创业项目推介、工作研讨、联谊活动、大会报告等活动,全面展示大学生最新的创新创业成果。年会共收到491所高校推荐的学术论文756篇、创新创业展示项目721项、创业推介项目156项,合计1633项,为历届年会数量最高。经过36所“985”高校相关学科专家的初评以及国家级大学生创新创业训练计划专家组的复选,最终遴选出可参加本次年会的学术论文180篇,创新创业展示项目150个,创业推介项目45项,共计375项,涉及30个省市的236所高校。年会还收到了来自澳门特别行政区、俄罗斯的13项学术论文及参展项目。这些材料集中反映了各高校最新的创新创业教育成果,也直接体现了当代大学生的创新思维和实践能力。
人脸识别项目实战
6ES7215-1AG40-0XB0_V04.04.01固件4.5
在无人机上部署SchurVins的yaml配置文件
uniapp实战商城类app和小程序源码,包含后端API源码和交互完整源码。
基于MobileNet轻量级网络实现的常见30多种食物分类,包含数据集、训练脚本、验证脚本、推理脚本等等。 数据集总共20k左右,推理的形式是本地的网页推理
2024年央国企RPA市场研究报.pdf