Introduction to Apache Wink
1. Overview
In this article, we will take a look at the Apache Wink Web Service examples. Apache Wink 1.0 is a JAX-RS 1.0 compliant and it has features related to the coreJAX-RS specification.
2. Apache Wink
Using Apache Wink, REST web services are built. REST is an acronym for “Representational State Transfer”. Roy Fielding was the first person to come up with the REST architecture proposal. In REST, a Resource is a Uniform Resource Identifier or URI. The state of a resource at any given point of time is represented by a document and is called the Representation of resources. REST differs from SOAP because it works on HTTP Protocol. REST has HTTP, GET, PUT, POST, and DELETE methods. Webservices exchange content using the producer and consumer pattern.
2.1 Prerequisites
Java 8 is required on the Linux, windows or mac operating system.Eclipse Oxygen can be used for this example. Apache Tomcat 9.0 is used as a servlet container to deploy the examples.
2.2 Download
You can download Java 8 from the Oracle web site . Eclipse Oxygen can be downloaded from the eclipse web site. Apache Tomcat 9.0 can be downloaded from the apache website.
2.3 Setup
Below are the setup commands required for the Java Environment.
Setup
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 Setup
The ‘eclipse-java-oxygen-2-macosx-cocoa-x86_64.tar’ can be downloaded from the eclipse website. The tar file is opened by double click. The tar file is unzipped by using the archive utility. After unzipping, you will find the eclipse icon in the folder. You can move the eclipse icon from the folder to applications by dragging the icon.
2.5 Launching IDE
2.5.1 Eclipse Java
Eclipse has features related to language support, customization, and extension. You can click on the eclipse icon to launch eclipse. The eclipse screen pops up as shown in the screenshot below:
You can select the workspace from the screen which pops up. The attached image shows how it can be selected.
You can see the eclipse workbench on the screen. The attached screenshot shows the Eclipse project screen.
Java Hello World
class prints the greetings. The screenshot below is added to show the class and execution on eclipse.
2.6 Apache Wink Rest Web Service
An Apache Wink web service is implemented as a plain Java class. It uses JAX-RS annotations to process incoming HTTP requests using Java methods. Let us see a web service example using a WinkWebService
class.
Apache Wink Rest WebService
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; } }
Now, You can see the WinkApplication
class which extends JAX-RS Application Class which adds the WinkWebService
in the getClasses
method.
Apache Wink Application
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; } }
In the WinkWebService
class, WinkPersistence Manager
is used to manage the Employee
Objects which are created, updated, deleted, and accessed. The code below shows the implementation of the WinkPersistenceManager
. which holds the singleton instance.
Persistence Manager
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 is used in the WinkPersistenceManager
. Employee
class is shown in the code below.
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; } }
Application file has the specified web service name configured in Web.xml.
application file
org.javacodegeeks.wink.rest.services.WinkWebService
Web.xml has the configuration of the RestServlet
. This servlet serves as the entry point for the apache wink REST Web service requests. This servlet processes the request by sending it to the web service.
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 is deployed on the tomcat using eclipse command – Run As -> Run on Server. The screenshot below shows the output.
Apache Wink has a web service client library for consuming RESTful services. Apache Wink Web service API has industry-standard data formats: XML, Atom, RSS, JSON, CSV, and HTML. WinkRestClient
class is shown below in the code snippet.
Wink Rest Client
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
executes Get, Post, Put, and Delete methods. This class is executed in eclipse using Run As -> Java Application. The screenshot below shows the output.
3. Download the Source Code
You can download the full source code of this example here: Introduction to Apache Wink