Wednesday, January 12, 2011

Creating REST Web Service using Java and Jersey API

In order to create a RESTful Web Service using Java, we need several tools and library
The tools and library which i used are:
1. Java 1.6
2. Eclipse IDE for Java EE developers (Ganymede)
3. Apache Tomcat (6.0)
4. Jersey API (1.4) . Download the zipped file.
5. Oracle Database 10g or any other DBMS

Create a new DynamicWebProject in Eclipse. If no such project template exists, you should download Eclipse for Java EE developers.
Copy those Jersey API librari in "WEB-INF\lib" folder
Modify web.xml to register our jersey servlet. Put any name on the servlet name tag. It doesn't matter.

<?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>NoteWS</display-name>
<servlet>
<servlet-name>JerseyTest</servlet-name>
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JerseyTest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
view raw web.xml hosted with ❤ by GitHub


Our web service will connect to database and retrieve or insert a new note in NOTE table
Create a new table named : NOTE with the following columns
NOTEID       : number
CONTENT   : varchar
CREATEDDATE : date

We will create a model class for that table: Note.java

package com.tukangjava.tutorial;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Note {
private int noteId;
private String content;
private Date createdDate;
public Note() {}
public Note(int noteId, String content, Date createdDate) {
this.noteId = noteId;
this.content = content;
this.createdDate = createdDate;
}
public int getNoteId() {
return noteId;
}
public void setNoteId(int noteId) {
this.noteId = noteId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
@Override
public String toString() {
return "Note [content=" + content + ", createdDate=" + createdDate
+ ", noteId=" + noteId + "]";
}
}
view raw Note.java hosted with ❤ by GitHub


Next, create a class that will handle connection with database: DatabaseAccess.java

package com.tukangjava.tutorial;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseAccess {
Connection connection = null;
public void connect() throws SQLException
{
String DRIVER = "oracle.jdbc.driver.OracleDriver";
String URL = "jdbc:oracle:thin:@127.0.0.1:1521:xe";
String UserName = "daniel";
String Password = "daniel";
try
{
Class.forName(DRIVER);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
try
{
connection = DriverManager.getConnection(URL,UserName,Password);
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public void disconnect() throws SQLException
{
connection.close();
}
}


After that, create a class that will handle the database operation. A Data Access Object :
NoteDao.java

package com.tukangjava.tutorial;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class NoteDao {
DatabaseAccess data;
Connection connection;
public NoteDao()
{
try {
data = new DatabaseAccess();
connect();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void connect() throws SQLException
{
try
{
data.connect();
connection = data.connection;
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public Note getNoteById(int id)
{
PreparedStatement prepStmt = null;
try {
String cSQL = "SELECT * FROM NOTE WHERE NOTEID = ? ";
prepStmt = connection.prepareStatement(cSQL);
prepStmt.setInt(1, id);
ResultSet result = prepStmt.executeQuery();
Note note = new Note();
while (result.next())
{
note.setNoteId(result.getInt(1));
note.setContent(result.getString(2));
note.setCreatedDate(new java.util.Date(result.getDate(3).getTime()));
}
return note;
} catch (SQLException e) {
e.printStackTrace();
prepStmt = null;
return null;
}
}
public List<Note> getAllNotes()
{
PreparedStatement prepStmt = null;
List<Note> notes = new ArrayList<Note>();
try {
String cSQL = "SELECT * FROM NOTE";
prepStmt = connection.prepareStatement(cSQL);
ResultSet result = prepStmt.executeQuery();
while (result.next())
{
Note note = new Note();
note.setNoteId(result.getInt(1));
note.setContent(result.getString(2));
note.setCreatedDate(new java.util.Date(result.getDate(3).getTime()));
notes.add(note);
}
return notes;
} catch (SQLException e) {
e.printStackTrace();
prepStmt = null;
return null;
}
}
public void addNote(Note note) {
PreparedStatement prepStmt = null;
try {
String cSQL = "INSERT INTO NOTE VALUES(?, ?, ?)";
prepStmt = connection.prepareStatement(cSQL);
prepStmt.setInt(1, note.getNoteId());
prepStmt.setString(2, note.getContent());
prepStmt.setDate(3, new Date(note.getCreatedDate().getTime()));
prepStmt.executeUpdate();
} catch (SQLException e) {
prepStmt = null;
e.printStackTrace();
}
}
}
view raw NoteDao.java hosted with ❤ by GitHub


Finally, we create a resource class that will be able to retrieved by the client using REST web service

package com.tukangjava.tutorial;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;
@Path("/notes")
public class NoteResource {
@Context
UriInfo uriInfo;
@Context
Request request;
NoteDao dao = new NoteDao();
@POST
@Produces(MediaType.TEXT_HTML)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void newNote(
@FormParam("noteId") String noteId,
@FormParam("content") String content,
@FormParam("createddate") String createddate,
@Context HttpServletResponse servletResponse
) throws IOException {
Note note = new Note();
note.setNoteId(Integer.parseInt(noteId));
note.setContent(content);
note.setCreatedDate(new Date(Long.parseLong(createddate)));
dao.addNote(note);
}
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public List<Note> getNotes() {
return dao.getAllNotes();
}
@Path("{note}")
@GET
@Produces(MediaType.APPLICATION_XML)
public Note getNote(
@PathParam("note") String idStr) {
int id = Integer.parseInt(idStr);
Note note = dao.getNoteById(id);
if(note==null)
throw new RuntimeException("Get: Note with " + id + " not found");
return note;
}
}


Save and deploy the project.
Populate our NOTE table using some dummy data and try to call our resource using the following URL in your web browser.

http://localhost:8080/NoteWS/notes

If u got xml file containing the records in your NOTE table. You have successfully create a REST Web Service.

Now, how can we use the POST method to actually insert a record.
Well, we can create a html form whose method is POST and submit action refers to

http://localhost:8080/NoteWS/notes

Something like this:
Notice that we have to make sure our text field name match the form parameter name defined in NoteResource.java

<html>
<body>
<form method="POST" action="http://localhost:8080/NoteWS/notes">
Note ID <input type="text" name="noteId" /><br />
Content <input type="text" name="content" /><br />
Created Date <input type="text" name="createddate" /><br />
<input type="submit" value="Submit" />
</form>
</body>
</html>
view raw note.html hosted with ❤ by GitHub


Note that createddate accept a String but in NoteResource.java it parses the string to primitive type long for creating new Date object. So, for now, just insert any number which will represent the second from January 1, 1970.

access http://localhost:8080/NoteWS/notes again to check our new note.

That is if for creating REST Web Service using Java and Jersey API.

Check out my other tutorial to find out how to consume this REST Web Service From
1. Simple java project
2. Android
3. iPhone

Have fun with REST!

2 comments: