本文将介绍 Apache Wink,一种用于构造 Representational State Transfer (REST)ful Web 服务的框架。Apache Wink 是一个 Apache Incubator 项目。它的目标是通过提供使用 Java™ 注释在类的内部定义服务的能力,提供一种简单的编写 RESTful Web 服务的方法。
REST
与 SOAP 不同,RESTful Web 服务并不一定需要 XML 文档作为消息载体。并没有标准的 XML Schema Definition(XSD) 描述消息格式。这使得 RESTful Web 服务可以像访问 URL 时返回的文档一样简单。实际上,Web 页面确实符合 RESTful Web 服务的配置文件。
由于消息格式并不需要使用 XML,因此几乎支持所有类型的消息内容。例如,可以将普通文本提交给 URL 以对一个 RESTful Web 服务调用 POST 方法。也可以使用其他简单消息格式,例如 JSON。Apache Wink 能够匹配 HTTP 操作中识别的 MIME 类型和使用并提供给定 MIME 类型的服务方法。
RESTful Web 服务使用不同的 HTTP 操作来公开服务,而这些服务执行不同的操作。尽管本身没有确定的标准,但有些原则定义了对特定的任务使用哪些 HTTP 操作。请看表 1。
表 1. REST 操作和 URL 示例
HTTP 操作 | URL 样例 | 用途 |
GET | http://localhost:8080/Task/rest/tasks | 列举出服务搜索到的所有任务 |
GET | http://localhost:8080/Task/rest/tasks/1 | 获得 ID 为 1 的任务 |
POST | http://localhost:8080/Task/rest/tsks | 根据提交的数据创建一个新任务 |
PUT | http://localhost:8080/Task/rest/tasks/1 | 使用数据请求更新 ID 为 1 的指定任务 |
DELETE | http://localhost:8080/Task/rest/tasks/1 | 删除 ID 为 1 的任务 |
wink需要的jar包:
wink-1.0-incubating.jar
wink-common-1.0-incubating.jar
wink-server-1.0-incubating.jar
导入 Apache Wink 库以后,从二进制版本的 lib 文件夹中导入以下依赖项:
activation-1.1.jar
commons-lang-2.3.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.4.jar
jsr311-api-1.0.jar
slf4j-api-1.5.8.jar
slf4j-simple-1.5.8.jar
stax-api-1.0-2.jar
清单 1. 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>Tasks</display-name>
<description>REST services for managing tasks.</description>
<servlet>
<servlet-name>restService</servlet-name>
<servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
<init-param>
<param-name>applicationConfigLocation</param-name>
<param-value>/WEB-INF/resources</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>restService</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
清单 2. WEB-INF/resources文件内容:
# Beans for REST Services
com.abc.ABCResource
com.abc.TasksResource
清单 3. 不具备实现的 TasksResource
类
package com.nathanagood.services;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
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.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.apache.wink.server.utils.LinkBuilders;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@Path("tasks")
public class TasksResource {
private static final String TASK = "tasks";
private static final String ITEM_PATH = "{tasks}";
private static final String ENCODING = "UTF-8";
@GET
@Produces( { MediaType.APPLICATION_JSON })
public JSONArray getTasks() {
// TODO: Add implementation
return null;
}
@Path(ITEM_PATH)
@GET
@Produces( { MediaType.APPLICATION_JSON })
public JSONObject getTask(@Context LinkBuilders link, @Context UriInfo uri,
@PathParam(TASK) String taskId) {
// TODO: Add implementation
return null;
}
@POST
@Consumes( { MediaType.APPLICATION_FORM_URLENCODED })
@Produces( { MediaType.APPLICATION_JSON })
public JSONObject createTask(MultivaluedMap<String, String> formData,
@Context UriInfo uriInfo, @Context LinkBuilders linksBuilders) {
// TODO: Add implementation
return null;
}
@Path(ITEM_PATH)
@PUT
@Consumes( { MediaType.APPLICATION_JSON })
@Produces( { MediaType.APPLICATION_JSON })
public JSONObject updateTask(JSONObject task, @Context UriInfo uriInfo,
@Context LinkBuilders linksBuilders) {
// TODO: Add implementation
return null;
}
@Path(ITEM_PATH)
@DELETE
@Produces( { MediaType.APPLICATION_JSON })
public JSONObject deleteTask(@Context LinkBuilders link, @Context UriInfo uri,
@PathParam(TASK) String taskId) {
// TODO: Add implementation
return null;
}
}
部署完成后,输入http://localhost:8080/Tasks/rest/tasks/1就可以测试了。