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.
Topics: JSON
Leave a comment
About Pathfinder
Follow the Blog
-
Get a monthly update on best practices for delivering successful software.
Subscribe via email
Subscribe via RSS
Categories
Topics
Archives
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006
Blogroll
Recent
- Elements of Testing Style
- Aesthetics and Web Design
- Asterisk-Java Testing with Groovy
- 3 Misuses of Code Comments
- Fluently NHibernate
- Digging a Hole and Covering it with Leaves — The Software Development Version
- The Importance of User Experience - Do You Understand It in Your Bones?
- Writing Your Own Protocol With NSURLProtocol
- What’s In Your Dock: iPhone edition
- Feature Fatigue
