Apache Wink的详细指南

156 阅读4分钟

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屏幕会弹出,如下图所示。

Apache Wink - Launching IDE

启动IDE

你可以在弹出的屏幕上选择工作区。附图显示了如何选择它。

Apache Wink - Eclipse Workspace

Eclipse工作区

你可以在屏幕上看到Eclipse工作区。附图显示了Eclipse项目的屏幕。

Apache Wink - Eclipse Workbench

Eclipse 工作台

JavaHello World 类打印出问候语。下面的截图是为了显示这个类和在eclipse上的执行情况。

Apache Wink - Java Hello

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在WinkPersistenceManagerEmployee 类中使用的代码如下所示。

雇员

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上的。下面的屏幕截图显示了输出。

Apache Wink

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执行。下面的屏幕截图显示了输出: