Recently, I came across “Foursquare” application on web and found it pretty interesting. This application lets user “checkin” to geographical locations and use that data to build cool applications. More information on Foursquare can be found on it’s about page: http://www.foursquare.com/about
I am going to write my experience with the API and how I managed to use it in Java.
Foursquare API v2
Foursquare has released v2 of their API and introduced some new features. It is a RESTful webservice which utilizes OAuth2 for the security/authentication and JSON for the communication over HTTPS protocol. It provides various “endpoints” and usually GET method is used for communication. Foursquare website also provides “explorer” application which can be used to test endpoints. (Explorer application can be found at: http://developer.foursquare.com/docs/explore.html)
Getting started with Foursquare API
To start building your application, you need to register with foursquare and get API credentials. These credentials are “client id”, “client secret” and “redirect URI”. These three items are required to communicate with foursquare webservice
Sample Application Code
Please download the source code here. I have written this very basic application demonstrating how to connect and exchange data with foursquare webservice in Java. Please use your own API credentials (I have removed them from the source code)
Application contains four servlets. Invoking “/login” servlet redirects user to foursquare login page while “/auth” servlet gets “access_token” required for authentication.
“/getvenues” servlet generates the table of nearby venues of given “ll” parameter (i.e. latitude and longitude).”/checkin” servlet checks-in the user at the given venue (identified by venueId parameter).
Communicating with Foursquare API
HttpURLConnection can be used to connect with foursquare webservice.
In the sample application, requests are sent using two different methods: getContent() and setContent()(for GET and POST requests respectively) found inside GetWebRes class
public String getContent(String httpurl){
try {
String sURL = httpurl;
URL url = new URL(sURL);
URLConnection httpc = url.openConnection();
httpc.setDoInput(true);
httpc.connect();
BufferedReader in = new BufferedReader(new InputStreamReader(httpc.getInputStream()));
String strLine = "";
String content="";
while ((strLine = in.readLine()) != null){
content=content+strLine;
}
return content;
} catch (Exception e) {
return ("Exception: " + e.getMessage());
}
}
public String setContent(String httpurl, String inputdata){
try {
String sURL = httpurl;
URL url = new URL(sURL);
HttpURLConnection httpc = (HttpURLConnection)url.openConnection();
httpc.setDoOutput(true);
httpc.setRequestMethod("POST");
httpc.connect();
OutputStreamWriter out = new OutputStreamWriter(httpc.getOutputStream());
out.write(inputdata);
out.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(httpc.getInputStream()));
String strLine="";
String content="";
while ((strLine = in.readLine()) != null){
content=content+strLine;
}
in.close();
out.close();
return content;
} catch (Exception e) {
return ("Exception: " + e.getMessage());
}
}
getContent() method sends the GET request and returns the data sent in response. Request parameters should be embedded in URL (as required by GET requests)
setMethod(), on the other hand, embeds request parameters in the body of request (using OutputStreamWriter) and returns the data sent in response. This method is used for POST based requests.
Authentication
Users accessing your application need to sign-in to their foursquare account. Once they are signed in, your application can access their data.
First step in authentication is to redirect your users to:
https://foursquare.com/oauth2/authenticate?client_id=CLIENT_ID&response_type=code&redirect_uri=REDIRECT_URI;
CLIENT_ID and REDIRECT_URI are your API credentials.
If user signs in, foursquare will send a “CODE” to the path specified in redirect_uri. For instance, if your request_uri is: http://localhost:8080/foursquare/auth , foursquare will send code as GET request to your application: http://localhost:8080/foursquare/auth?code=CODE
This code is then embedded in your request to get “access_token” from foursquare. This “access_token” will be a part of all your requests to foursquare webservice. To get access_token, a GET request is sent:
https://foursquare.com/oauth2/access_token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&redirect_uri=REDIRECT_URI&code=CODE
CLIENT_ID, CLIENT_SECRET and REDIRECT_URI are your API credentials while CODE is the code sent by foursquare when user signs in.
In the sample application, authentication is done by invoking “/login” (login.java). “login” servlet redirects the user to foursquare.
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//API Credentials
String client_id="HTX3FYAVTJOV2NR3NOS5RGOMBRNYIVJD55T2BIZ4DDSHJRJB";
String client_secret="5W33FKDZ11UY3V23OBAM0AODFXYLVMTUORAAWYCSUHPT2WW4";
String redirect_uri="http://localhost:8080/foursquare/auth";
//Set Session Variables
HttpSession session = request.getSession(true);
session.setAttribute("client_key", client_id);
session.setAttribute("client_secret", client_secret);
session.setAttribute("redirect_uri", redirect_uri);
try {
//Redirect User to foursquare login page
String url="https://foursquare.com/oauth2/authenticate?client_id="+client_id+"&response_type=code&redirect_uri="+redirect_uri;
response.sendRedirect(url);
} finally {
out.close();
}
After user signs in, foursquare sends code to redirect uri, which in this case is http://localhost:8080/foursquare/auth?code=CODE
“auth” servlet processes the CODE and builds request to get access_token
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String code=request.getParameter("code");
//Instatiate GetWebRes Object
GetWebRes webrs = new GetWebRes();
//Get Session Variables
HttpSession session = request.getSession(true);
String client_key=(String)session.getAttribute("client_key");
String client_secret=(String)session.getAttribute("client_secret");
String redirect_uri=(String)session.getAttribute("redirect_uri");
//If code is not null
if (!code.equals("")){
String url="https://foursquare.com/oauth2/access_token?client_id="+client_key+"&client_secret="+client_secret+"&grant_type=authorization_code&redirect_uri="+redirect_uri+"&code="+code;
String content=webrs.getContent(url);
//JSON Parsing using GSON Library
OauthToken oauthtoken = new Gson().fromJson(content, OauthToken.class);
//Store Oauth token in session
session.setAttribute("access_token", oauthtoken.getAccess_Token());
out.println("Authenticated Successfully!");
//Redirect to welcome page
response.sendRedirect(request.getContextPath() + "/getvenues");
}else{
out.println("Error: Could not authenticate");
}
Access_token is sent in JSON format which is then parsed by the application
Parsing JSON responses
There are several APIs available to parse JSON. I have used GSON and JSON-Simple libraries in the sample application to demonstrate how they function.
Parsing using GSON
GSON library can be downloaded from http://code.google.com/p/google-gson.
GSON library allows you to map java object to JSON for retrieving information. For instance, JSON text: {key1:”value1” , key2:”value”} can be mapped to java object:
String jsonstring = "{\"key1\":\"value1\" , \"key2\":\"value\"}";
JsonToObject obj = new Gson().fromJson(jsonstring, JsonToObject.class);
Class JsonToObject{
private String key1;
private String key2;
public String getKey1(){return key1;}
public void setKey1(String key1){this.key1=key1}
public String getKey2(){return key2;}
public void setKey2(String key2){this.key2=key2}
}
In sample application, “auth” servlet uses GSON to parse “access_token”
OauthToken oauthtoken = new Gson().fromJson(content, OauthToken.class);
session.setAttribute("access_token", oauthtoken.getAccess_Token());
class OauthToken{
private String access_token;
public String getAccess_Token(){return access_token;}
public void setAccess_Token(String accesstoken){
this.access_token=accesstoken;
}
}
Parsing using JSON-Simple
JSON-Simple can be downloaded from http://code.google.com/p/json-simple
This library allows easy parsing of JSON. Below is the example of JSON-Simple parsing:
content = "{\"key1\": \"value1\", \"key2\" : [1,{\"abc\":\"123\" , \"xyz\":\"456\"}]}";
Object obj=JSONValue.parse(content);
JSONObject main_obj=(JSONObject)obj;
out.println(main_obj.get("key1")); //Output: value1
JSONArray key2_arr = (JSONArray)main_obj.get("key2");
JSONObject abcxyz_obj = (JSONObject)key2_arr.get(1);
out.println(abcxyz_obj.get("xyz")); // Output: 456
In the sample application, “getvenues” servlet uses this library. After sending webservice a GET request to access all the nearby venues of given latitude and longitude values, the response sent by webservice is parsed using JSON Simple. Please look at the servlet to know more about JSON-Simple parsing.
Accessing resource
Any endpoint can be accessed by sending a GET or POST request. Details of endpoints can be found at: http://developer.foursquare.com/docs/index_docs.html
Care should be taken in providing the required parameters like access_token as webservice will respond with error code “400” if the parameters are missing.
Creating a resource
Resource can be created on foursquare webservice by sending POST request with data. For instance, to add a “checkin” by user, POST request is sent with venueId, access_token and other optional parameters as data.
In sample application, “checkin” servlet adds a checkin using setContent() method of GetWebRes class.
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//instantiate GetWebResource object
GetWebRes webrs = new GetWebRes();
//Get Session Variables
HttpSession session = request.getSession(true);
String access_token=(String)session.getAttribute("access_token");
//If AccessToken is not created
if (access_token == null){
//Redirect to login page
response.sendRedirect(request.getContextPath() + "/login");
}
//Get venueid and broadcast parameters from request object
String venueid = request.getParameter("venueid");
String broadcast = request.getParameter("broadcast");
if ((venueid != null) && (broadcast != null)){
String url="https://api.foursquare.com/v2/checkins/add";
String inputdata = "venueId="+venueid+"&broadcast="+broadcast+"&oauth_token="+access_token;
String content=webrs.setContent(url,inputdata);
//out.println(content);
//Extract message from JSON response usin JSON-Simple lib
Object obj=JSONValue.parse(content);
JSONObject main_obj=(JSONObject)obj;
JSONArray notifications_arr = (JSONArray)main_obj.get("notifications");
JSONObject notification_obj = (JSONObject)notifications_arr.get(0);
JSONObject item_obj = (JSONObject)notification_obj.get("item");
if (item_obj.get("message")!=null){
out.println(item_obj.get("message"));
}else{
out.println("Error: Checkin was not successful");
}
}else{
out.println ("Error: broadcast and venueid parameters missing");
}
out.close();
}
Nice post, very helpful, but your link to your source code is broken… care to update?
Thanks!
Updated the link,… thanks!
where should i register myself to get credentials?
https://foursquare.com/oauth/
You need to register at their website first: https://foursquare.com/signup/
I love the Gson implementation. It makes the world a better place
Have you had any experience mapping the /user/self/badges request with a json object?
This tut is really helpful for me. Thanks a lot.
However, it seems that the source code have not been packaged into the war file that you provide.
hxxp://snasir.net/files/foursquare-java/foursquare.war
Can you check it please ? Thanks.
True that – I found the same thing. there are only class files at snasir.net/files/foursquare-java/foursquare.war and no source code -
could you share the github URL if you have posted your code there? that would be good enough.
Thank you for pointing that out. I have updated the link!
can i implement this tutorial in android ?