Due: Friday, Feb 10th Tuesday, Feb 14th by 11:59 PM
This is an individual assignment
Getting Started
Download CS496_Assignment2.zip and import into Eclipse. There should be three projects created:
- CS496_Jetty - this project contains Jetty and other useful Java libraries.
- CS496_Assign2Server - a web service that uses RESTful requests, i.e. GET, PUT, POST, and DELETE, to manage a product inventory
- CS496_Assign2Mobile - a mobile client that produces RESTful requests and displays output based on the response from the server
The assignment consists of creating a web service and mobile client to manage a basic inventory system.
Your Tasks
You have two tasks:
- Modify CS496_Assign2Server so that it implements the RESTful API described in Lab 02.
- Modify CS496_Assign2Mobile so that it implements an Android user interface allowing the user to access and modify the inventory using the RESTful API provided by the server.
Implementing the Web Service
The requirements for the web service are described in Lab 02.
You can use a web browser to test the GET method of the web service. Right click Launcher, then Run As->Java Application, then enter a URL of the form
http://localhost:8081/resource name
where resource name is inventory or inventory/item name.
You can use curl to test your implementation of the PUT, POST, and DELETE methods: see Lab 02 for details. Use the web browser to check that the modification to the inventory was carried out correctly.
Hints
For full credit, make sure that your web service gracefull and correctly handles incorrect input. For example, if a PUT request contains a message body that does not contain a single Item element with Name and Quantity child elements (each with appropriate data as the element text), then the HTTP response returned to the client should indicate a status code of 400, Bad Request.
For extra credit, use thread synchronization to ensure that the inventory model object will be updated correctly even if multiple clients are accessing the web service concurrently.
Implementing the Mobile Client
The provided mobile client layout (in main.xml) creates:
- two EditText components allowing the user to enter an item name and quantity
- four Button components allowing the user to send either a GET, PUT, POST, or DELETE request using the information from the EditText boxes
- one Button component to show the current inventory stored on the server
The requirements for the mobile client are that it should retrieve the information from the EditText boxes (i.e. the item name and quantity) and produce the appropriate request based on the button clicked as follows:
- Get - with no item name entered in the EditText box should display the entire inventory (not as XML) using the same dynamic layout as Show Inventory described below. With an item name entered in the EditText box, should create a GET URI to retrieve just that item (if it exists in the inventory) and display it using the same dynamic layout as Show Inventory described below but only containing a single item.
- Put - should require that an item name and quantity are in the EditText boxes, create valid XML for the item (see the Hints below), and send a PUT request with the XML as the payload to update the specified item.
- Post - should require that an item name and quantity are in the EditText boxes, create valid XML for the item, and send a POST request with the XML as the payload to add the new item.
- Delete - with no item name entered in the EditText box should delete the entire inventory. With an item name entered in the EditText box, should create a DELETE URI to delete just that item (if it exists in the inventory).
- Show Inventory - should display the current inventory on the server in a new dynamic layout that contains a Back button to return the user to the original data entry view.
Since Put, Post, and Delete do not generate output, display a Toast message informing the user as to what action has been performed (and if it was successfully completed)
The inventory layout should look like
Hints
To access localhost through the Android emulator, you need to use the IP address 10.0.2.2.
Use separate methods for each of the REST requests that are called from the corresponding button click callbacks. In each method instantiate the appropriate HttpGet, HttpPut, HttpPost, or HttpDelete object.
Create two methods for setting the layout - one that loads the initial one from main.xml and the other which creates a dynamic LinearLayout view. Call each of these methods as needed from button click methods. Have the dynamic layout method take an Inventory parameter (allowing it to be reused for displaying either the entire inventory retrieved from the server or an inventory consisting of just a single item).
To parse XML from a Document (e.g. from a response), you can use Elements from the org.w3c.dom library.
NodeList nodeList = doc.getElementsByTagName("Foo");
will create a list of all the Foo nodes in the document. From there you can iterate through the list and select a particular node Element as
Element element = (Element) nodeList.item(i);
The children within an Element can then be extracted (as NodeList's) in a similar fashion, e.g. to get the value of the "Bar" child (assuming there is only one) as a string
NodeList barList = element.getElementsByTagName("Bar");
Element barElement = (Element) barList.item(0);
barList = barElement.getChildNodes();
barValue = ((Node) barList.item(0)).getNodeValue();
Consider adding a fromElement(Element e) method to the Item class that takes an item element obtained from the document's NodeList and constructs a new Item object by calling this method (which will parse the XML for an item). Then add the items to an Inventory object in the application which can then be subsequently displayed.
To generate XML, you can use a XMLSerializer object to create a String as follows:
XMLSerializer serializer = new XMLSerializer();
StringWriter writer = new StringWriter();
try {
serializer.setOutput(writer);
serializer.startDocument("UTF-8",true);
serializer.startTag("","Outer Tag");
serializer.startTag("","Inner Tag");
serializer.text("Inner Tag value");
serializer.endTag("","Inner Tag");
serializer.endTag("","Outer Tag");
serializer.endDocument();
return writer.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
which would generate the following XML:
<?xml version="1.0" encoding="utf-8"?>
<Outer Tag>
<Inner Tag>
Inner Tag Value
</Inner Tag>
</Outer Tag>
Add a method in the item class, e.g. toXML() that utilizes a similar procedure to create valid XML for an item, i.e. contains an Item that has Name and Quantity children. Then call this method for those requests that require an XML payload and create a StringEntity object from the returned string that can be placed into the request using request.setEntity().
Grading
Your grade will be assigned as follows:
- Web service:
- PUT: 15%
- POST: 10%
- DELETE: 15%
- strict validation of request and request data: 10%
- thread synchronization (bonus): 5%
- Mobile app:
- Original input layout: 5%
- Dynamic output layout: 5%
- Get - 15%
- Put - 10%
- Post - 10%
- Delete - 5%
Submitting
Please submit the Eclipse projects CS496_Assign2Server and CS496_Assign2Mobile separately to the Marmoset inboxes assign2server and assign2mobile.
Using Simple Marmoset Uploader
If you have the Simple Marmoset Uploader plugin available (it is installed on all KEC computers, and you are encouraged to install it on your own computer), you can select the project in the package explorer and then click the blue up arrow button that looks like this:
Type your Marmoset username password when prompted.
Manually
If you can't use Simple Marmoset Uploader, use File->Export->Archive File separately for each project, and upload the resulting zip files to Marmoset as assign2server and assign2mobile:
https://cs.ycp.edu/marmoset/
Check your upload
Please log into Marmoset to check the files you submitted to make sure you submitted what you intended to.
CS 496 - Assignment 2: RESTful Web Server and Mobile Client
