Tags: google visualization api
JSON Restful Web Service in Java
By MD on May 23, 2008 | In Ease Of Use | Send feedback »
What kind of ways are available to get JSON Restful Web Service in Java?
Wait, what is JSON? Also Restful Web Service exactly?
Actually, I got to know them only a couple of weeks ago.
If you have tried XML Web Service with SOAP, you probably know how hard to get performance, and ease of use without complexity(especially about schema binding).
Then, JSON Restful Web Service must be what you will get interested in.
Let's go back to the first question. You can think of two providers. Sun and Apache. Here're options to go first.
In my opinion, they're just a topping on top of XML Web Service. That is the very basic mismatch. Feel free to try if you need to make sure
This is the one, with which you can get a true power of JSON Restful Web Service.
Take a look at Introduction on the site if you are not 100% sure about Restful Web Service(REST).
I'm going to show you an example to implement a service that returns DataTable compatible with one of Google Visualization API. The source of information is this thread in Google Visualization Discussion.
Code:
<CHUNK1> | |
google.visualization.Query.setResponse( | |
{ | |
requestId:'0', | |
status:'ok', | |
signature:'6173382439516707022', /* Changes when data changes */ | |
</CHUNK1> | |
So the timeseries gadget must download this JSON every so often and | |
check the new signature against it's own. If the signature is | |
different, it knows that the data on the "spreadsheet" has changed. | |
<CHUNK2> | |
table:{ | |
cols: | |
[ | |
{ | |
id:'A', | |
label:'Date', | |
type:'d', /* d=date */ | |
pattern:'M/d/yyyy' /* unique date pattern */ | |
}, | |
{ | |
id:'B', | |
label:'Budget', | |
type:'n', /* n=number */ | |
pattern:'#0.###############' /* unique number pattern */ | |
}, | |
{ | |
id:'C', | |
label:'Revenue', | |
type:'n', | |
pattern:'#0.###############' | |
}, | |
{ | |
id:'D', | |
label:'Movie', | |
type:'t', /* t=text */ | |
pattern:'' /* there is no text pattern */ | |
} | |
], | |
</CHUNK2> | |
Chunk2 shows the columns needed for a timeseries chart. (Date, | |
Value1, ..., ValueN, PopupText) | |
Note the type and pattern fields. d=date, n=number, t=text | |
<CHUNK3> | |
rows: | |
[ | |
[ | |
{ | |
v:new Date(1981,10,6), | |
f:'11/6/1981' | |
}, | |
{ | |
v:5000000.0, | |
f:'5000000' | |
}, | |
{ | |
v:4.2365581E7, | |
f:'42365581' | |
}, | |
{ | |
v:'Time Bandits' | |
} | |
], | |
</CHUNK3> |
To get this type of JSON Object is the goal. So how to do this?
In order to understand the following code, you may want to learn the tutorial how Restlet models the resource oriented Restfull world.
Restlet
Code:
import org.restlet.Application; | |
import org.restlet.Context; | |
import org.restlet.Restlet; | |
import org.restlet.Router; | |
| |
public class JSONApplication extends Application { | |
| |
public JSONApplication() { | |
super(); | |
} | |
| |
public JSONApplication(Context arg0) { | |
super(arg0); | |
} | |
| |
@Override | |
public Restlet createRoot() { | |
Router router = new Router(getContext()); | |
| |
router.attach("/table", JSONTableResource.class); | |
| |
return router; | |
} | |
| |
} |
Table Resource and JSON Representation
Code:
import org.json.JSONArray; | |
import org.json.JSONException; | |
import org.json.JSONObject; | |
import org.restlet.Context; | |
import org.restlet.data.CharacterSet; | |
import org.restlet.data.MediaType; | |
import org.restlet.data.Request; | |
import org.restlet.data.Response; | |
import org.restlet.data.Status; | |
import org.restlet.ext.json.JsonRepresentation; | |
import org.restlet.resource.Representation; | |
import org.restlet.resource.Resource; | |
import org.restlet.resource.ResourceException; | |
import org.restlet.resource.Variant; | |
| |
public class JSONTableResource extends Resource { | |
| |
private static final String JSON_NAME_TABLE = "table"; | |
| |
private static final String JSON_NAME_COLUMNS = "cols"; | |
private static final String JSON_NAME_COLUMNS_ID = "id"; | |
private static final String JSON_NAME_COLUMNS_LABEL = "label"; | |
private static final String JSON_NAME_COLUMNS_TYPE = "type"; | |
private static final String JSON_NAME_COLUMNS_PATTERN = "pattern"; | |
| |
private static final String JSON_NAME_ROWS = "rows"; | |
private static final String JSON_NAME_ROWS_V = "v"; | |
private static final String JSON_NAME_ROWS_F = "f"; | |
| |
public JSONTableResource(Context context, Request request, Response response) { | |
super(context, request, response); | |
| |
getVariants().add(new Variant(MediaType.APPLICATION_JSON)); | |
} | |
| |
@Override | |
public Representation represent(Variant variant) throws ResourceException { | |
JSONObject json = new JSONObject(); | |
| |
try { | |
| |
json.put("requestId", "0"); | |
json.put("status", "ok"); | |
json.put("signature", "6173382439516707022"); | |
| |
json.put(JSON_NAME_TABLE, this.createTable()); | |
| |
} catch (JSONException e) { | |
throw new ResourceException(Status.SERVER_ERROR_INTERNAL); | |
} | |
| |
JsonRepresentation jr = new JsonRepresentation(json); | |
| |
jr.setCharacterSet(CharacterSet.UTF_8); | |
| |
return jr; | |
} | |
| |
private JSONObject createTable() throws JSONException{ | |
JSONArray columns = new JSONArray(); | |
JSONArray rows = new JSONArray(); | |
JSONObject r_c = new JSONObject(); | |
r_c.put(JSON_NAME_COLUMNS, columns); | |
r_c.put(JSON_NAME_ROWS, rows); | |
| |
this.createColumns(columns); | |
this.createRows(rows); | |
| |
return r_c; | |
} | |
| |
private void createColumns(JSONArray columns) throws JSONException{ | |
| |
columns.put(this.createColumn("A", "Date", "d", "M/d/yyyy")); | |
columns.put(this.createColumn("B", "Budget", "n", "#0.###############")); | |
columns.put(this.createColumn("C", "Revenue", "n", "#0.###############")); | |
columns.put(this.createColumn("D", "Movie", "t", "")); | |
| |
} | |
| |
private void createRows(JSONArray rows) throws JSONException{ | |
| |
JSONArray row = new JSONArray(); | |
| |
row.put(this.createCell("new Date(1981,10,6)", "11/6/1981")); | |
row.put(this.createCell("5000000.0", "5000000")); | |
row.put(this.createCell("4.2365581E7", "42365581")); | |
row.put(this.createCell("Time Bandits", null)); | |
| |
rows.put(row); | |
| |
} | |
| |
private JSONObject createCell(String v, String f) throws JSONException{ | |
JSONObject jo = new JSONObject(); | |
jo.put(JSON_NAME_ROWS_V, v); | |
if(f != null) | |
jo.put(JSON_NAME_ROWS_F, f); | |
return jo; | |
} | |
| |
private JSONObject createColumn(String id, String label, String type, String pattern) throws JSONException{ | |
JSONObject jo = new JSONObject(); | |
jo.put(JSON_NAME_COLUMNS_ID, id); | |
jo.put(JSON_NAME_COLUMNS_LABEL, label); | |
jo.put(JSON_NAME_COLUMNS_TYPE, type); | |
jo.put(JSON_NAME_COLUMNS_PATTERN, pattern); | |
return jo; | |
} | |
| |
} |
web.xml
XML:
<?xml version="1.0" encoding="UTF-8"?> | |
<web-app id="WebApp_ID" version="2.4" | |
xmlns="http://java.sun.com/xml/ns/j2ee" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee | |
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> | |
<display-name>first steps servlet</display-name> | |
<!−− Application class name −−> | |
<context-param> | |
<param-name>org.restlet.application</param-name> | |
<param-value> | |
firstSteps.JSONApplication | |
</param-value> | |
</context-param> | |
| |
<!−− Restlet adapter −−> | |
<servlet> | |
<servlet-name>RestletServlet</servlet-name> | |
<servlet-class> | |
com.noelios.restlet.ext.servlet.ServerServlet | |
</servlet-class> | |
</servlet> | |
| |
<!−− Catch all requests −−> | |
<servlet-mapping> | |
<servlet-name>RestletServlet</servlet-name> | |
<url-pattern>/json/*</url-pattern> | |
</servlet-mapping> | |
</web-app> |
You can get JSON Object in Java here.
Here's the JSON texts you'll get.
Code:
{"status":"ok","requestId":"0", | |
"table": | |
{"cols":[ | |
{"id":"A","pattern":"M/d/yyyy","label":"Date","type":"d"}, | |
{"id":"B","pattern":"#0.###############","label":"Budget","type":"n"}, | |
{"id":"C","pattern":"#0.###############","label":"Revenue","type":"n"}, | |
{"id":"D","pattern":"","label":"Movie","type":"t"} | |
], | |
"rows":[ | |
[ | |
{"f":"11/6/1981","v":"new Date(1981,10,6)"}, | |
{"f":"5000000","v":"5000000.0"}, | |
{"f":"42365581","v":"4.2365581E7"}, | |
{"v":"Time Bandits"} | |
] | |
] | |
}, | |
"signature":"6173382439516707022"} |
Then, you can call the service, get DataTable, then process to visualize. Here's an example to show a simple table in Ajax.
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | |
<html> | |
<head> | |
<script type="text/javascript"> | |
| |
var xhr; | |
try { xhr = new ActiveXObject('Msxml2.XMLHTTP'); } | |
catch (e) | |
{ | |
try { xhr = new ActiveXObject('Microsoft.XMLHTTP'); } | |
catch (e2) | |
{ | |
try { xhr = new XMLHttpRequest(); } | |
catch (e3) { xhr = false; } | |
} | |
} | |
| |
xhr.open("GET", JSON_RESTFULL_WEB_SERVICE_URL, true); | |
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); | |
xhr.send(null); | |
| |
xhr.onreadystatechange = function() | |
{ | |
if(xhr.readyState == 4) | |
{ | |
if(xhr.status == 200){ | |
the_object = eval( "(" + xhr.responseText + ")" ); | |
handleQueryResponse(the_object.table); | |
}else{ | |
| |
} | |
} | |
}; | |
| |
// Query response handler function. | |
function handleQueryResponse(table) { | |
| |
var html = []; | |
html.push('<table border="1">'); | |
| |
// Header row | |
html.push('<tr><th>Seq</th>'); | |
for (var col = 0; col < table.cols.length; col++) { | |
html.push('<th>' + escapeHtml(table.cols[col].label) + '</th>'); | |
} | |
html.push('</tr>'); | |
| |
for (var row = 0; row < table.rows.length; row++) { | |
html.push('<tr><td align="right">' + (row + 1) + '</td>'); | |
for (var col = 0; col < table.cols.length; col++) { | |
html.push(table.cols[col].type == 'number' ? '<td align="right">' : '<td>'); | |
html.push(escapeHtml(table.rows[row][col].f)); | |
html.push('</td>'); | |
} | |
html.push('</tr>'); | |
} | |
html.push('</table>'); | |
| |
document.getElementById('tablediv').innerHTML = html.join(''); | |
} | |
| |
function escapeHtml(text) { | |
if (text == null) | |
return ''; | |
| |
return text.replace(/&/g, '&') | |
.replace(/</g, '<') | |
.replace(/>/g, '>') | |
.replace(/"/g, '"'); | |
} | |
| |
</script> | |
</head> | |
| |
<body> | |
<div id="tablediv">Loading...</div> | |
</body> | |
</html> |
Simple, Fast, and Flexible. Experience JSON Restful Web Service!