101 Ideas for JSONP - Idea #1: RSS to JSONP

I've been working with lots of Ajax projects that make use of JSONP. JSONP is basically wrapping JSON in a callback script. So a return such as the following

callback({"IBM":"82.53"});

allows you to include the call as a script tag, for example

var script = document.createElement("script");
script.src = 'http://remoteserver/stockquote?symbol=IBM&callback=renderQuotes';
script.type = 'text/javascript';
document.body.appendChild(script);

will dynamically add a script to our page which will call back an already existing function renderQuotes in our page. This technique is very useful if you are including Ajax widgets on remote sites or using bookmarklets or GreaseMonkey scripts to pull information from remote servers.

Now you can use some ready made JSONP capable web services to build your applications and mashups -- certainly Yahoo has quite a few -- but that won't get you all of the types of information that you might want. Proxying other sites and sources of information and turning the results into JSON is a good way of getting the content you need.

I'm starting a little series called "101 Ideas for JSONP," where I'll give 101 different techniques, sources and ideas for getting information into a JSONP service.

Idea #1: RSS to JSONP

RSS is an XML format for content syndication widely used by just about everybody. The JSON library from json.org is a handy little utility library that allows you to convert JSON to and from XML and Java Objects. Combine the two and you've got an easy way of providing a JSONP service.

I've got an example of this right here that takes the RSS feed for New York City resumes from Craig's List and transforms it into JSONP.

resumes

The above widget updates every 30 seconds (you can look at the Javascript file that populates it from the proxy server here). The code we use to get the RSS and transform it into JSONP is pretty basic. The one thing to note in the code below is that the org.json.XML class doesn't allow for streaming. That means we have to read the whole RSS feed into memory in order to convert it. That's really not an issue in most cases with RSS feeds, but it's a gap that I'll try to remedy at some point in the near future.

package com.pathf.demo.jsonideas;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.XML;
import org.json.JSONException;
import java.io.IOException;

public class RSSGetter {
private HttpClient httpClient;
private Log log = LogFactory.getLog(RSSGetter.class);

public RSSGetter() {
httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
}

public String getRSS(String uri) {
// we get it as a string, since the JSON lib doesn't handle streams
GetMethod get = new GetMethod(uri);
get.setFollowRedirects(true);
try {
httpClient.executeMethod(get);
return get.getResponseBodyAsString();
} catch (IOException e) {
log.error("Problem getting rss feed " + uri, e);
return "Problem getting RSS feed";
}
}

public String getJSONRSS(String uri) {
try {
return XML.toJSONObject(getRSS(uri)).toString();
} catch (JSONException e) {
e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
return "{\"Result\":\"Error\"}";
}
}
}

The servlet below just wraps the result of the RSS retrieval in the callback function that is passed as a parameter. If no callback parameter is passed, it reverts to plain old JSON.

package com.pathf.demo.jsonideas;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.ServletConfig;
import java.io.IOException;

public class NYCResumeServlet extends HttpServlet {
private RSSGetter rss = null;
private static final String NYC_RESUMES = "http://newyork.craigslist.org/res/index.rss";

protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
httpServletResponse.setContentType("text/javascript");
String callback = httpServletRequest.getParameter("callback");
String json = rss.getJSONRSS(NYC_RESUMES);
if (callback == null) {
httpServletResponse.getOutputStream().println(json);
} else {
httpServletResponse.getOutputStream().println(callback + "(" + json + ");");
}
}

public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
rss = new RSSGetter();
}
}

There are other ways of pulling in an RSS feed via JSONP, some of which will allow us to use the browser's machinery for operating on XML to transform and add content via remote widgets.



Technorati : , , ,


Topics:

Leave a comment

Powered by WP Hashcash

About Pathfinder

Follow the Blog

    Get a monthly update on best practices for delivering successful software.

    Subscribe via email

      

    Subscribe via RSS      RSS icon

Topics

Search

WordPress

Comments about this site: info@pathf.com