Membuat RESTful Web Services di Java dengan Jersey

Membangung RESTful Web services yang memungkinkan anda untuk mengeluarkan data anda secara mudah, dalam berbagai format (xml, json, dll), dan dilengkapi dengan abstraksi (menyembunyikan hal hal low-level pada komunikasi client-server) bukanlah hal yang mudah tanpa toolkit yang handal. Blog post ini akan berbagi cara membangun RESTful Web services di Java menggunakan Jersey.

Informasi lengkap mengenai Jersey bisa dilihat disini. tutorial menggunakan jersey bisa dilihat di tutorialpoint atau di vogella. Pada kesempatan ini saya membuat sebuah aplikasi java web sederhana, tanpa IU, isinya web service saja. kasusnya pun sederhana, aplikasi web ini bisa meresponse request atas web service untuk menangani operasi CRUD pada database (postgresql). tutorial connection pooling di postgresql bisa dilihat disini. Jangan lupa, dalam menyediakan koneksi ke database harus menggunakan singleton, sebab koneksi ke database ini boros resources. Tutorial mengenai singleton bisa dilihat disini.

apa yang saya sampaikan diatas, sudah saya buat project java di eclipse IDE, dan bisa di download disini. itu adalah java web eclipse project, jadi tinggal import saja.

berikut adalah penjelasan mengani 4 kode java yang ada disana.

User.java

ini adalah java bean biasa dengan 3 property (id, name, dan profession), lengkap dengan getter dan setter. satu lagi, ditambah dengan Serializable supaya bisa disimpan dalam sebuah file.

package com.tutorialspoint;  

import java.io.Serializable;  
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
@XmlRootElement(name = "user") 

public class User implements Serializable {  
	private static final long serialVersionUID = 1L; 
	private int id; 
	private String name; 
	private String profession;  
	public User(){} 

	public User(int id, String name, String profession){  
		this.id = id; 
		this.name = name; 
		this.profession = profession; 
	}  
	public int getId() { 
		return id; 
	}  
	@XmlElement 
	public void setId(int id) { 
		this.id = id; 
	} 
	public String getName() { 
		return name; 
	} 
	@XmlElement
	public void setName(String name) { 
		this.name = name; 
	} 
	public String getProfession() { 
		return profession; 
	} 
	@XmlElement 
	public void setProfession(String profession) { 
		this.profession = profession; 
	}   
} 

UserDao.java

ini adalah kode java untuk data access object. kode java ini memfasilitasi proses untuk menarik data dari file, dan proses menyimpan data dari ke file.

package com.tutorialspoint;  

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException;  
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.util.ArrayList; 
import java.util.List;  

public class UserDao { 
	@SuppressWarnings("unchecked")
	public List<User> getAllUsers(){ 

		List<User> userList = null; 
		try { 
			File file = new File("Users.dat");
			if (!file.exists()) { 
				User user = new User(1, "Zaien", "CTO");
				User user2 = new User(1, "Ahmad", "CEO"); 
				User user3 = new User(1, "Agas", "CIO"); 
				userList = new ArrayList<User>(); 
				userList.add(user);
				userList.add(user2);
				userList.add(user3);
				saveUserList(userList); 
			} 
			else{ 
				FileInputStream fis = new FileInputStream(file); 
				ObjectInputStream ois = new ObjectInputStream(fis); 
				userList = (List<User>) ois.readObject(); 
				ois.close(); 
			} 
		} catch (IOException e) { 
			e.printStackTrace(); 
		} catch (ClassNotFoundException e) { 
			e.printStackTrace(); 
		}   
		return userList; 
	}
	
	@SuppressWarnings("unchecked")
	public User getFirstUsers(){ 

		List<User> userList = null; 
		try { 
			File file = new File("Users.dat");
			if (!file.exists()) { 
				User user = new User(1, "Zaien", "CTO");
				userList = new ArrayList<User>(); 
				userList.add(user);
				saveUserList(userList); 
			} 
			else{ 
				FileInputStream fis = new FileInputStream(file); 
				ObjectInputStream ois = new ObjectInputStream(fis); 
				userList = (List<User>) ois.readObject(); 
				ois.close(); 
			} 
		} catch (IOException e) { 
			e.printStackTrace(); 
		} catch (ClassNotFoundException e) { 
			e.printStackTrace(); 
		}
		
		if (userList.size()>0){
			User firstUser=userList.get(0);
			return firstUser;
		} else
			return null;
		
	}
	
	private void saveUserList(List<User> userList){ 
		try { 
			File file = new File("Users.dat"); 
			FileOutputStream fos;  
			fos = new FileOutputStream(file); 
			ObjectOutputStream oos = new ObjectOutputStream(fos); 
			oos.writeObject(userList); 
			oos.close(); 
		} catch (FileNotFoundException e) { 
			e.printStackTrace(); 
		} catch (IOException e) { 
			e.printStackTrace(); 
		} 
	}    
}

ConnectionProvider.java

ini adalah kode java untuk data connection pool ke postgresql. mengapa pakai connection pool? untuk menghemat koneksi. jadi kalau ada koneksi yang idle, bisa dipakai ulang dan tidak perlu membuat koneksi baru. ConnectionProvider dibangun dengan konsep singleton. artinya kita tidak bisa membuat object ConnectionProvider dengan perintah new. sehingga tidak ada kebocoran memori, dimana ConnectionProvider sudah dibuat, lalu ditempat lain dibuat lagi, dan lagi, dan lagi. dengan singleton, bisa dijamin, object ConnectionProvider hanya dibuat 1x seumur hidup, dan untuk mendapatkan object connection (sql connection) adalah melalui method getConnection().

package com.tutorialspoint;

import java.sql.Connection;
import java.sql.SQLException;

import org.postgresql.ds.PGPoolingDataSource;

public class ConnectionProvider {
	private static PGPoolingDataSource pgpool = null;
	
	/* A private Constructor prevents any other
	 * class from instantiating.
	 */
	private ConnectionProvider() {}
	
	/* Static 'instance' method */
	public static Connection getConnection( ) {
		if (pgpool==null)
			pgpool=createNewPgPool();
		
		Connection connection = null;
		try {
			connection = pgpool.getConnection();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return connection;
			
	}

	private static PGPoolingDataSource createNewPgPool() {
		PGPoolingDataSource source = new PGPoolingDataSource();
		source.setDataSourceName("infinite@localhost");
		source.setServerName("localhost");
		source.setPortNumber(5432);
		source.setDatabaseName("infinite");
		source.setUser("postgres");
		source.setPassword("postgres");
		source.setMaxConnections(10);
		
		return source;
	}
	
}

web.xml

perhatikan isi xml berikut ini

<?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" 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>User Management</display-name> 
   <servlet> 
      <servlet-name>Jersey RESTful Application</servlet-name> 
      <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> 
      <init-param> 
         <param-name>jersey.config.server.provider.packages</param-name> 
         <param-value>com.tutorialspoint</param-value> 
      </init-param> 
   </servlet> 
   <servlet-mapping> 
      <servlet-name>Jersey RESTful Application</servlet-name> 
      <url-pattern>/rest/*</url-pattern> 
   </servlet-mapping>   
</web-app>

perhatikan content <url-pattern>/rest/*</url-pattern> dimana ini menjelaskan jika web service kita memiliki URL <application URL>/rest/*. artinya, jika server container (apache tomcat) di install di localhost dengan port 8080, dan project eclipse ini dinamai UserManagement, maka URL untuk web service ini adalah http://localhost:8080/UserManagement/rest/*.

UserService.java

ini adalah kode java yang menangani pemanggilan web service. perhatikan ada annotation @Path(“/UserService”) , artinya java class ini akan meresponse web service dengan URL <application URL>/UserService/*. perhatikan juga annotation @Path(“/users”), artinya method com.tutorialspoint.UserService.getUsers() akan meresponse web service request dengan method GET dan URL <application URL>/UserService/users. mengapa method yang diresponse adalah method GET dan bukan yang lain (POST, PUT, DELETE, dll)? karena pada method getUsers() tersebut terdapat annotation @GET.

kembali merujuk pada page sebelumnya yang membahas web.xml, dimana URL web service nya adalah  http://localhost:8080/UserManagement/rest/*, maka pada contoh diatas, URL untuk mengakses method getUsers() adalah http://localhost:8080/UserManagement/rest/UserService/users.

perhatikan betapa mudahnya membuat RESTful Web services dengan jersey ini. cukup menggunakan annotation dan embed jar library jersey ini, anda sudah memiliki aplikasi yang memiliki public API.

package com.tutorialspoint;  

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.MediaType;  
@Path("/UserService") 

public class UserService {  
	UserDao userDao = new UserDao();  
	@GET 
	@Path("/users") 
	@Produces(MediaType.APPLICATION_JSON) 
	public List<User> getUsers(){ 
		return userDao.getAllUsers(); 
	}
	
	
	@GET 
	@Path("/firstuser") 
	@Produces(MediaType.TEXT_PLAIN) 
	public String getFirstUsers(){ 
		User firstuser = userDao.getFirstUsers();
		if (firstuser!=null){
			return "name: "+firstuser.getName()+", profession: "+firstuser.getProfession();
		} else
			return "no user available";
		
	}
	
	@GET 
	@Path("/infiniteuser") 
	@Produces(MediaType.APPLICATION_XML) 
	public List<User> getInfiniteUsers(){
		List<User> output = new ArrayList<>();
		String sql = "select name, title, ad_client_id from ad_user where ad_client_id='EFDCC00043B14801B1279AEDCE53D6E9'";
		Connection conn = null;
		try
		{
		    conn = ConnectionProvider.getConnection();
		    
		    // use connection
		    PreparedStatement ps = conn.prepareStatement(sql);
		    ResultSet rs = ps.executeQuery();
		    int id=0;
		    while (rs.next()){
		    	id++;
		    	String name = rs.getString("name");
		    	String title = rs.getString("title");
		    	User user = new User(id, name, title);
		    	output.add(user);
		    }
		}
		catch (SQLException e)
		{
		    // log error
		}
		catch (Exception e)
		{
		    // log error
		}
		finally
		{
		    if (conn != null)
		    {
		        try { conn.close(); } catch (SQLException e) {}
		    }
		}
		
		
		return output;
		
	}
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s