RESTful Web Services - Methods

As we have already discussed, a RESTful web service makes heavy use of HTTP verbs to define the operation to be performed on the specified resources. The following table provides examples of common usage of HTTP verbs.
HTTP method | RECEIVE |
---|---|
URI | http://localhost:8080/usermanagement/rest/userservice/users |
operation | Get a list of users |
Type of transaction | Only reading |
HTTP method | RECEIVE |
---|---|
URI | http://localhost:8080/usermanagement/rest/userservice/users/1 |
operation | Get User Id 1 |
Type of transaction | Only reading |
HTTP method | MESSAGE |
---|---|
URI | http://localhost:8080/usermanagement/rest/userservice/users/2 |
operation | Insert user with id 2 |
Type of transaction | Non-idempotent |
HTTP method | PUT |
---|---|
URI | http://localhost:8080/usermanagement/rest/userservice/users/2 |
operation | Update user with id 2 |
Type of transaction | N/A |
HTTP method | DELETE |
---|---|
URI | http://localhost:8080/usermanagement/rest/userservice/users/1 |
operation | Delete user with id 1 |
Type of transaction | idempotent |
HTTP method | OPTIONS |
---|---|
URI | http://localhost:8080/usermanagement/rest/userservice/users |
operation | List of supported operations in a web service |
Type of transaction | Only reading |
HTTP method | HEAD |
---|---|
URI | http://localhost:8080/usermanagement/rest/userservice/users |
operation | Returns HTTP header only, no body |
Type of transaction | Only reading |
Here are the important points to consider:
-
GET operations are read-only and safe.
-
The PUT and DELETE operations are idempotent, so their result will always be the same, no matter how many times these operations are called.
-
The PUT and POST operations are almost the same, with the only difference being that the PUT operation is idempotent, while the POST operation may lead to different results.
GET operations are read-only and safe.
The PUT and DELETE operations are idempotent, so their result will always be the same, no matter how many times these operations are called.
The PUT and POST operations are almost the same, with the only difference being that the PUT operation is idempotent, while the POST operation may lead to different results.
example
Let's update the example created in the RESTful Web Services - First Application tutorial to create a Web service that can perform CRUD (Create, Read, Update, Delete) operations. For simplicity, we have used file I/O to replace database operations.
Update UserService.java , User.java , UserDao.java files in com.tutorialspoint package.
User.java
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 Stringname ; _ 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 ; } @Override public boolean equals ( Object object ){ if ( object == null ){ return false ; } else if (!( object instanceof User )){ return false ; } else { User user = ( User ) object ; if ( id == user . getId () && name . equals ( user . getName ()) && profession . equals ( user . getProfession ()) ) { return true ; } } return false ; } }
UserDao.java
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 { public List < User > getAllUsers (){ List < User > userList = null ; try { File file = new File ( "Users.dat" ); if (! file . exists ()) { User user = new User ( 1 , "Mahesh" , "Teacher" ); 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 (); } return userList ; } public User getUser ( int id ){ List < User > users = getAllUsers (); for ( User user : users ){ if ( user . getId () == id ){ return user ; } } return null ; } public int addUser ( User pUser ){ List < User > userList = getAllUsers (); boolean userExists = false ; for ( User user : userList ){ if ( user . getId () == pUser . getId ()){ userExists = true ; break ; } } if (! userExists ){ userList . add ( pUser ); saveUserList ( userList ); return 1 ; } return 0 ; } public int updateUser ( User pUser ){ List < User > userList = getAllUsers (); for ( User user : userList ){ if ( user . getId () == pUser . getId ()){ int index = userList . indexOf ( user ); userList . set ( index , pUser ); saveUserList ( userList ); return 1 ; } } return 0 ; } public int deleteUser ( int id ){ List < User > userList = getAllUsers (); for ( User user : userList ){ if ( user . getId () == id ){ int index = userList . indexOf ( user ); userList . remove ( index ); saveUserList ( userList ); return 1 ; } } return 0 ; } 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 (); } } }
UserService.java
package.com . _ tutorialspoint ; import java . io . IOException ; import java . util . List ; import javax . server . http . HttpServletResponse ; import javax . ws . rs . Consumes ; import javax . ws . rs . DELETE ; import javax . ws . rs . FormParam ; import javax . ws . rs . GET ; import javax . ws . rs . OPTIONS ; 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 . Context ; import javax . ws . rs . core . mediatype ; @Path ( "/UserService" ) public class UserService { UserDao userDao = new UserDao (); private static final String SUCCESS_RESULT = "success " ; private static final String FAILURE_RESULT = "failure " ; @GET @Path ( "/users" ) @Produces ( MediaType . APPLICATION_XML ) public List < User > getUsers (){ return userDao . getAllUsers (); } @GET @Path ( "/users/{userid}" ) @Produces ( MediaType . APPLICATION_XML ) public User getUser ( @PathParam ( "userid" ) int userid ){ return userDao . getUser ( userid ); } @POST @Path ( "/users" ) @Produces ( MediaType . APPLICATION_XML ) @Consumes ( MediaType . APPLICATION_FORM_URLENCODED ) public String createUser ( @FormParam ( "id" ) int id , @FormParam ( "name" ) String name , @FormParam ( "profession" ) String profession , @Context HttpServletResponse servletResponse ) throws IOException { User user = new User ( id , name , profession ); int result = userDao . addUser ( user ); if ( result == 1 ){ return SUCCESS_RESULT ; } return FAILURE_RESULT ; } @PUT @Path ( "/users" ) @Produces ( MediaType . APPLICATION_XML ) @Consumes ( MediaType . APPLICATION_FORM_URLENCODED ) public String updateUser ( @FormParam ( "id" ) int id , @FormParam ( "name" ) String name , @FormParam ( "profession" ) String profession , @Context HttpServletResponse servletResponse ) throws IOException { User user = new User ( id , name , profession ); int result = userDao . updateUser ( user ); if ( result == 1 ){ return SUCCESS_RESULT ; } return FAILURE_RESULT ; } @DELETE @Path ( "/users/{userid}" ) @Produces ( MediaType . APPLICATION_XML ) public String deleteUser ( @PathParam ( "userid" ) int userid ){ int result = userDao . deleteUser ( userid ); if ( result == 1 ){ return SUCCESS_RESULT ; } return FAILURE_RESULT ; } @OPTIONS @Path ( "/users" ) @Produces ( MediaType . APPLICATION_XML ) public String getSupportedOperations (){ return "GET, PUT, POST, DELETE " ; } }
Now, using Eclipse, export your application as a war file and deploy it to tomcat. To create a WAR file with eclipse select File -> Export -> Web > War File and finally select the Project UserManagement and destination folder. To deploy the war file to Tomcat, place the UserManagement.war file in the Tomcat installation directory > webapps directory and start Tomcat.
Web service testing
Jersey provides an API to create a web service client for testing web services. We created a sample WebServiceTester.java test class in the com.tutorialspoint package in the same project.
WebServiceTester.java
package.com . _ tutorialspoint ; import java . util . List ; import javax . ws . rs . client . Client ; import javax . ws . rs . client . ClientBuilder ; import javax . ws . rs . client . entity ; import javax . ws . rs . core . form ; import javax . ws . rs . core . Generic Type ; import javax . ws . rs . core . mediatype ; public class WebServiceTester { private Client client ; private String REST_SERVICE_URL = "http://localhost:8080/UserManagement/rest/UserService/users" ; private static final String SUCCESS_RESULT = "success " ; private static final String PASS = "pass" ; private static final String FAIL = "fail" ; private void init (){ this . client = ClientBuilder . newClient (); } public static void main ( String [] args ){ WebServiceTester tester = new WebServiceTester (); //initialize the tester tester . init (); //test get all users Web Service Method tester . testGetAllUsers (); //test get user Web Service Method tester . testGetUser (); //test update user Web Service Method tester . testUpdateUser (); //test add user Web Service Method tester . testAddUser (); //test delete user Web Service Method tester . testDeleteUser (); } //Test: Get list of all users //Test: Check if list is not empty private void testGetAllUsers (){ GenericType < List < User >> list = new GenericType < List < User >>() {}; List < User > users = client . target ( REST_SERVICE_URL ) . request ( MediaType . APPLICATION_XML ) . get ( list ); String result = PASS ; if ( users . isEmpty ()){ result = FAIL ; } System . out . println ( "Test case name: testGetAllUsers, Result: " + result ); } //Test: Get User of id 1 //Test: Check if user is same as sample user private void testGetUser (){ User sampleUser = new User (); sampleUser . setId ( 1 ); User user = client . target ( REST_SERVICE_URL ) . path ( "/{userid}" ) . resolveTemplate ( "userid" , 1 ) . request ( MediaType . APPLICATION_XML ) . get ( User.class ) ; _ String result = FAIL ; if ( sampleUser != null && sampleUser . getId () == user . getId ()){ result = PASS ; } System . out . println ( "Test case name: testGetUser, Result: " + result ); } //Test: Update User of id 1 //Test: Check if result is success XML. private void testUpdateUser (){ Form form = new Form (); form . param ( "id" , "1" ); form . param ( "name" , "suresh" ); form . param ( "profession" , "clerk" ); String callResult = client . target ( REST_SERVICE_URL ) . request ( MediaType . APPLICATION_XML ) . put ( Entity . entity ( form , MediaType . APPLICATION_FORM_URLENCODED_TYPE ), String . class ); String result = PASS ; if (! SUCCESS_RESULT . equals ( callResult )){ result = FAIL ; } System . out . println ( "Test case name: testUpdateUser, Result: " + result ); } //Test: Add User of id 2 //Test: Check if result is success XML. private void testAddUser (){ Form form = new Form (); form . param ( "id" , "2" ); form . param ( "name" , "naresh" ); form . param ( "profession" , "clerk" ); String callResult = client . target ( REST_SERVICE_URL ) . request ( MediaType . APPLICATION_XML ) . post ( Entity . entity ( form , MediaType . APPLICATION_FORM_URLENCODED_TYPE ), String . class ); String result = PASS ; if (! SUCCESS_RESULT . equals ( callResult )){ result = FAIL ; } System . out . println ( "Test case name: testAddUser, Result: " + result ); } //Test: Delete User of id 2 //Test: Check if result is success XML. private void testDeleteUser (){ String callResult = client . target ( REST_SERVICE_URL ) . path ( "/{userid}" ) . resolveTemplate ( "userid" , 2 ) . request ( MediaType . APPLICATION_XML ) . delete ( String . class ); String result = PASS ; if (! SUCCESS_RESULT . equals ( callResult )){ result = FAIL ; } System . out . println ( "Test case name: testDeleteUser, Result: " + result ); } }
Now run the tester using Eclipse. Right-click on the file and select the option Run as -> Java Application . In the Eclipse console, you will see the following output: