1.概述
在这篇文章中,我们将看一下Apache Wink Web Service的例子。Apache Wink 1.0是一个符合JAX-RS 1.0的版本,它具有与核心JAX-RS规范相关的功能。
2.Apache Wink
使用Apache Wink,可以构建REST Web服务。 REST是 "Representational State Transfer "的首字母缩写。Roy Fielding是第一个提出REST架构建议的人。在REST中,资源是一个统一的资源标识符或URI。一个资源在任何给定时间点的状态由一个文件来表示,被称为资源的表示。REST与SOAP不同,因为它在HTTP协议上工作。REST有HTTP、GET、PUT、POST和DELETE方法。Webservices使用生产者和消费者模式交换内容。
2.1 先决条件
在Linux、windows或mac操作系统上需要使用Java 8。Eclipse Oxygen可用于本例。Apache Tomcat 9.0被用来作为servlet容器来部署这个例子。
2.2 下载
你可以从Oracle网站上下载Java 8。Eclipse Oxygen可以从eclipse网站上下载。Apache Tomcat 9.0可以从apache网站上下载。
2.3 设置
下面是Java环境所需的设置命令。
设置
JAVA_HOME="/desktop/jdk1.8.0_73"
export JAVA_HOME
PATH=$JAVA_HOME/bin:$PATH
export PATH
2.4 IDE
2.4.1 Eclipse Oxygen设置
eclipse-java-oxygen-2-macosx-cocoa-x86_64.tar'可以从eclipse网站下载。通过双击打开该tar文件。使用存档工具来解压该tar文件。解压后,你会在文件夹中发现eclipse图标。你可以通过拖动图标将eclipse图标从文件夹中移到应用程序中。
2.5 启动IDE
2.5.1 Eclipse Java
Eclipse具有与语言支持、定制和扩展有关的功能。你可以点击eclipse图标来启动eclipse。eclipse屏幕会弹出,如下图所示。
启动IDE
你可以在弹出的屏幕上选择工作区。附图显示了如何选择它。
Eclipse工作区
你可以在屏幕上看到Eclipse工作区。附图显示了Eclipse项目的屏幕。
Eclipse 工作台
JavaHello World
类打印出问候语。下面的截图是为了显示这个类和在eclipse上的执行情况。
Java Hello
2.6 Apache Wink休息网络服务
一个Apache Wink网络服务被实现为一个普通的Java类。它使用JAX-RS注解,用Java方法处理传入的HTTP请求。 让我们看看一个使用WinkWebService
类的Web服务例子。
Apache Wink休息网络服务
package org.javacodegeeks.wink.rest.services;
import java.util.List;
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.core.MediaType;
import org.javacodegeeks.wink.rest.pojo.Employee;
import org.javacodegeeks.wink.rest.repository.WinkPersistenceManager;
@Path("employees")
public class WinkWebService {
WinkPersistenceManager persistenceManager = WinkPersistenceManager.getInstance();
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getEmployees() {
List employees = persistenceManager.get();
String empList = new String("");
for(Employee employee: employees) {
empList+=employee.toString() + "\n";
}
return empList;
}
@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_XML)
public Employee getEmployeeById(@PathParam(value="id") long id) {
System.out.println(id);
Employee employee = persistenceManager.getEmployee(id);
return employee;
}
@GET
@Path("/json/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Employee getEmployeeJsonById(@PathParam(value="id") long id) {
Employee employee = persistenceManager.getEmployee(id);
return employee;
}
@POST
public String addEmployees(String employee) {
Employee emp = new Employee();
emp.setName(employee);
persistenceManager.add(emp);
return employee;
}
@DELETE
@Path("/{id}")
public void deleteEmployee(@PathParam(value="id") long id) {
persistenceManager.delete(id);
return;
}
@PUT
@Path("/{id}")
public void modifyEmployee(@PathParam(value="id") long id, String empName) {
persistenceManager.update(id, empName);
return;
}
}
现在,你可以看到WinkApplication
类,它扩展了JAX-RS应用类,在getClasses
方法中添加了WinkWebService
。
Apache Wink应用程序
package org.javacodegeeks.wink.rest.application;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;
import org.javacodegeeks.wink.rest.services.WinkWebService;
public class WinkApplication extends Application {
@Override
public Set<Class> getClasses() {
Set<Class> classes = new HashSet<Class>();
classes.add(WinkWebService.class);
return classes;
}
@Override
public Set getSingletons() {
Set set = new HashSet();
ObjectMapper objMapper = new ObjectMapper();
AnnotationIntrospector primary = new JaxbAnnotationIntrospector();
AnnotationIntrospector secondary = new JaxbAnnotationIntrospector();
AnnotationIntrospector pair = AnnotationIntrospector.pair(primary, secondary);
objMapper.getDeserializationConfig().withAnnotationIntrospector(pair);
objMapper.getSerializationConfig().withAnnotationIntrospector(pair);
JacksonJaxbJsonProvider jaxbProvider = new JacksonJaxbJsonProvider();
jaxbProvider.setMapper(objMapper);
set.add(jaxbProvider);
return set;
}
}
在WinkWebService
类中,WinkPersistence Manager
被用来管理被创建、更新、删除和访问的Employee
对象。下面的代码显示了WinkPersistenceManager
.的实现,它持有单子实例。
持久性管理器
package org.javacodegeeks.wink.rest.repository;
import java.util.ArrayList;
import java.util.List;
import org.javacodegeeks.wink.rest.pojo.Employee;
public class WinkPersistenceManager {
private List employeeList = new ArrayList();
private static WinkPersistenceManager manager;
private static int id=0;
private WinkPersistenceManager() {
}
public Employee getEmployee(long empId) {
System.out.println("Finding Employee " + empId);
Employee employee = null;
boolean found = false;
for(int i=0;i<employeeList.size();i++) {
employee = employeeList.get(i);
if(employee.getId()==empId) {
found = true;
break;
}
}
if(!found) employee=null;
return employee;
}
public void add(Employee employee) {
System.out.println("Adding Employee");
id++;
employee.setId(id);
employeeList.add(employee);
}
public List get() {
System.out.println(" all employees");
return employeeList;
}
public void update(long empId, String empName) {
System.out.println("Updating Employee");
for(int i=0;i<employeeList.size();i++) {
Employee employee = employeeList.get(i);
if(employee.getId()==empId) {
employee.setName(empName);
employeeList.remove(i);
employeeList.add(i,employee);
}
}
return;
}
public void delete(long empId) {
System.out.println("removing the employee");
for(int i=0;i<employeeList.size();i++) {
Employee employee = employeeList.get(i);
if(employee.getId()==empId) employeeList.remove(i);
}
return;
}
public static WinkPersistenceManager getInstance() {
if(manager==null) {
synchronized(WinkPersistenceManager.class) {
if(manager==null) {
manager = new WinkPersistenceManager();
}
}
}
return manager;
}
}
Employee
Pojo在WinkPersistenceManager
。Employee
类中使用的代码如下所示。
雇员
package org.javacodegeeks.wink.rest.pojo;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="employee")
public class Employee {
long id;
String name;
@XmlAttribute
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@XmlElement(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
String strForm="id=" + this.id + ", name=" + this.name;
return strForm;
}
}
应用文件在Web.xml中配置了指定的网络服务名称。
应用文件
org.javacodegeeks.wink.rest.services.WinkWebService
Web.xml中有RestServlet
的配置。这个servlet作为apache wink REST Web服务请求的入口点。这个servlet通过将请求发送到Web服务来处理。
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_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>products</display-name>
<servlet>
<servlet-name>restWinkService</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>org.javacodegeeks.wink.rest.application.WinkApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>restWinkService</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
WinkWebservice是通过eclipse命令--运行为--在服务器上运行--部署在tomcat上的。下面的屏幕截图显示了输出。
Wink网络服务的部署
Apache Wink有一个用于消费RESTful服务的Web服务客户端库。Apache Wink网络服务API具有行业标准的数据格式。XML、Atom、RSS、JSON、CSV和HTML。WinkRestClient
类的代码片断如下所示。
Wink休息客户端
package org.javacodegeeks.wink.rest.client;
import javax.ws.rs.core.MediaType;
import org.apache.wink.client.ClientConfig;
import org.apache.wink.client.ClientResponse;
import org.apache.wink.client.Resource;
import org.apache.wink.client.RestClient;
public class WinkRestClient {
static String REST_WEB_SERVICE = "http://localhost:8080/ApacheWink/rest/employees";
static ClientConfig clientConfig = new ClientConfig();
public static void main(String[] args) throws Exception {
try {
WinkRestClient winkRestClient = new WinkRestClient();
winkRestClient.executeGetMethod();
System.out.println();
String product = "John Smith" + (int) (Math.random() * 9999);
winkRestClient.executePostMethod(product);
System.out.println();
product = "Baron Wells" + (int) (Math.random() * 9999);
winkRestClient.executePostMethod(product);
System.out.println();
product = "Thomas Smith" + (int) (Math.random() * 9999);
winkRestClient.executePostMethod(product);
System.out.println();
product = "George Ryon" + (int) (Math.random() * 9999);
winkRestClient.executePostMethod(product);
System.out.println();
winkRestClient.executeGetMethod();
System.out.println();
winkRestClient.executeDeleteMethod(1L);
System.out.println();
winkRestClient.executeGetMethod();
System.out.println();
product = "Barry Reilly" + (int) (Math.random() * 9999);
winkRestClient.executePostMethod(product);
System.out.println();
product = "John Booch" + (int) (Math.random() * 9999);
winkRestClient.executePostMethod(product);
System.out.println();
winkRestClient.executeDeleteMethod(3L);
System.out.println();
winkRestClient.executeGetMethod();
System.out.println();
winkRestClient.executePutMethod(3L, "Will Hamilton");
System.out.println();
winkRestClient.executeGetMethod();
System.out.println();
winkRestClient.executeJsonGetMethod(3);
System.out.println();
winkRestClient.executeJsonGetMethod(2);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
public void executeGetMethod() {
System.out.println("Testing GET method....");
RestClient restClient = new RestClient(clientConfig);
Resource resource = restClient.resource(REST_WEB_SERVICE);
String response = resource.accept("text/plain").get(String.class);
System.out.printf(response);
System.out.println("GET method is executed");
}
public void executePostMethod(String employee) {
System.out.println("Testing POST method...");
RestClient restClient = new RestClient(clientConfig);
Resource resource = restClient.resource(REST_WEB_SERVICE);
resource.contentType(MediaType.TEXT_PLAIN).accept(MediaType.TEXT_PLAIN).post(String.class, employee);
System.out.println("POST method is executed");
}
public void executePutMethod(Long id, String name) {
System.out.println("Testing PUT method");
RestClient restClient = new RestClient(clientConfig);
Resource resource = restClient.resource(REST_WEB_SERVICE + "/" + id);
resource.contentType(MediaType.TEXT_PLAIN).accept(MediaType.TEXT_PLAIN).put(String.class, name);
System.out.println("PUT method is executed");
}
public void executeDeleteMethod(Long id) {
System.out.println("Testing DELETE method");
RestClient restClient = new RestClient(clientConfig);
Resource resource = restClient.resource(REST_WEB_SERVICE + "/" + id);
resource.contentType(MediaType.TEXT_PLAIN).accept(MediaType.TEXT_PLAIN).delete();
System.out.println("DELETE method is executed");
}
public void executeJsonGetMethod(long id) {
System.out.println("Testing JSON GET method");
RestClient restClient = new RestClient(clientConfig);
Resource resource = restClient.resource(REST_WEB_SERVICE + "/json/" + id);
ClientResponse response = resource.accept(MediaType.APPLICATION_JSON).get();
System.out.println("JSON GET method is executed");
}
public void executeJAXBGetMethod(long id) {
System.out.println("Testing JAXB GET method");
RestClient restClient = new RestClient(clientConfig);
Resource resource = restClient.resource(REST_WEB_SERVICE + "/" + id);
ClientResponse response = resource.accept(MediaType.APPLICATION_XML).get();
System.out.println("JAXB GET method is executed");
}
}
WinkRestClient
执行Get、Post、Put和Delete方法。这个类在eclipse中使用Run As -> Java Application执行。下面的屏幕截图显示了输出: