Skip to content

Struts Sample

tarun-nagpal edited this page Jun 26, 2013 · 3 revisions

###Introduction This is the step by step guide to show how to develop a Struts application using socialauth library. If you just want to see the application working, please see our demo

###Prerequisites
Authenticating using the external oAuth providers requires that we register our application with the providers and obtain a key/secret from them that will be configured in our application. So following steps are needed to be set up before we can begin.

  1. Public domain - You will need a public domain for testing. You should have a public domain because most of the providers require a public domain to be specified when you register an application with them.
  2. Get the API Keys: You can get the API keys from the following URLs. * Google (show screenshot) - http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html * Yahoo (show screenshot) - https://developer.apps.yahoo.com/dashboard/createKey.html * Twitter - http://twitter.com/apps * Facebook - http://www.facebook.com/developers/apps.php * Hotmail (show screenshot) - http://msdn.microsoft.com/en-us/library/cc287659.aspx * FourSquare - (show screenshot) - https://foursquare.com/oauth/ * MySpace - (show screenshot) - http://developer.myspace.com/Apps.mvc * Linkedin - (show screenshot) - https://www.linkedin.com/secure/developer * Salesforce - (show screenshot) * Yammer - (show screenshot) - https://www.yammer.com/client_applications * Mendeley - (show screenshot) - http://dev.mendeley.com/applications/register/
  • You can now develop the application using keys and secrets obtained above and deploy the application on your public domain. However, most people need to test the application on a local development machine using the API keys and secrets obtained above.
  • We do not recommend it at all, but if you do not want to obtain your own keys and secrets while testing, you can use the keys and secrets that we obtained by registering "opensource.brickred.com" for our demo. Follow the same steps as above but with domain as "opensource.brickred.com" and keys from our sample.

###Development With the prerequisites out of the way, we are ready to begin development. Since Eclipse is our choice of the development environment, we have shown examples using Eclipse.

###Step 1. Create eclipse maven project Create a maven web project in eclipse and provide groupId and artifactId. Lets say groupId is "org.brickred" and artifactId is "socialauth-struts-demo". It will create directory structure similar to as given below. Some folder like jsp, css, images you'll have to create manually. Directory Structure
###Step 2. Add following dependency in pom.xml file.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>org.brickred</groupId>
	<artifactId>socialauth-struts-demo</artifactId>
	<version>1.0</version>
	<packaging>war</packaging>

	<name>socialauth-struts-demo</name>
	<url>http://maven.apache.org</url>

	<dependencies>
		<dependency>
			<groupId>org.brickred</groupId>
			<artifactId>socialauth</artifactId>
			<version>[4.2,)</version>
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>2.1.8</version>
			<exclusions>
				<exclusion>
					<artifactId>tools</artifactId>
					<groupId>com.sun</groupId>
				</exclusion>
			</exclusions>
		</dependency>

		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-convention-plugin</artifactId>
			<version>2.1.8</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.3</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>1.1.2</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
			<scope>runtime</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.5.1</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.1-beta-1</version>
				<configuration>
					<warName>socialauthdemo</warName>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<repositories>
		<repository>
			<id>sonatype-oss-public</id>
			<url>https://oss.sonatype.org/content/groups/public/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
		</repository>
	</repositories>
</project>

###Step 3. Web.xml file Make following configuration in web.xml file for Struts2.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">
	<display-name>Struts 2 Web Application</display-name>

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>*.do</url-pattern>
	</filter-mapping>
    
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>


###Step 4. oauth_consumer.properties file Create oauth_consumer.properties file in src\main\java folder and configure application clienId and clientSecret for various providers. You can copy keys from our sample

###Step 5. struts.properties file In Struts 2, all action class has a default suffix .action extension. Create struts.properties file if you want to change it. In this example we are using .do as extension.

struts.action.extension=action,do,etc

###Step 6. Coding the index page Now let us code the index page with the following code. In this page, we just create various icons that the user can click upon and attach them with the action that will process the authentication. Here attached action in “socialauth.do” which maps to the “org.brickred.actions.SocialAuthenticationAction”.


<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@page isELIgnored="false"%>
<style type="text/css">
.style1 {
    text-align: justify;
}
</style>
<script>
	function validate(obj) {
		var val = obj.id.value;
		if (trimString(val).length <= 0) {
			alert("Please enter OpenID URL");
			return false;
		} else {
			return true;
		}
	}
	function trimString(tempStr) {
		return tempStr.replace(/^\s*|\s*$/g, "");
	}
</script>
<c:set var="facebook" value="false" />
<c:set var="twitter" value="false" />
<c:set var="google" value="false" />
<c:set var="yahoo" value="false" />
<c:set var="hotmail" value="false" />
<c:set var="linkedin" value="false" />
<c:set var="foursquare" value="false" />
<c:set var="myspace" value="false" />
<c:set var="salesforce" value="false" />
<c:set var="yammer" value="false" />
<c:set var="mendeley" value="false" />
<c:forEach var="item" items="${socialAuthManager.connectedProvidersIds}">
	<c:if test="${item eq 'facebook'}">
		<c:set var="facebook" value="true" />
	</c:if>
	<c:if test="${item eq 'google'}">
		<c:set var="google" value="true" />
	</c:if>
	<c:if test="${item eq 'twitter'}">
		<c:set var="twitter" value="true" />
	</c:if>
	<c:if test="${item eq 'yahoo'}">
		<c:set var="yahoo" value="true" />
	</c:if>
	<c:if test="${item eq 'hotmail'}">
		<c:set var="hotmail" value="true" />
	</c:if>
	<c:if test="${item eq 'linkedin'}">
		<c:set var="linkedin" value="true" />
	</c:if>
	<c:if test="${item eq 'myspace'}">
		<c:set var="myspace" value="true" />
	</c:if>
	<c:if test="${item eq 'foursquare'}">
		<c:set var="foursquare" value="true" />
	</c:if>
	<c:if test="${item eq 'salesforce'}">
		<c:set var="salesforce" value="true" />
	</c:if>
	<c:if test="${item eq 'yammer'}">
		<c:set var="yammer" value="true" />
	</c:if>
	<c:if test="${item eq 'mendeley'}">
		<c:set var="mendeley" value="true" />
	</c:if>
</c:forEach>

<div id="main">

	<div id="text">
		<table cellpadding="10" cellspacing="10" align="center">
			<tr>
				<td colspan="8"><h3 align="center">Welcome to Social Auth
						Demo</h3></td>
			</tr>
			<tr>
				<td colspan="8"><p align="center">Please click on any icon.</p></td>
			</tr>
			<tr>
				<td>
					<div style="width: 48px; height: 41px;">
						<a href="socialAuth.do?id=facebook"><img
							src="images/facebook_icon.png" alt="Facebook" title="Facebook"
							border="0"></img></a>
					</div>
					<div>
						<c:if test="${facebook eq true}">
							<a href="socialAuth.do?id=facebook&mode=signout">Signout</a>
						</c:if>
						<c:if test="${facebook eq false}">
							<a href="socialAuth.do?id=facebook">Signin</a>
							<br />
						</c:if>
					</div>
				</td>
				<td>
					<div style="width: 48px; height: 41px;">
						<a href="socialAuth.do?id=twitter"><img
							src="images/twitter_icon.png" alt="Twitter" title="Twitter"
							border="0"></img></a>
					</div>
					<div>
						<c:if test="${twitter eq true}">
							<a href="socialAuth.do?id=twitter&mode=signout">Signout</a>
						</c:if>
						<c:if test="${twitter eq false}">
							<a href="socialAuth.do?id=twitter">Signin</a>
							<br />
						</c:if>
					</div>
				</td>
				<td>
					<div style="width: 48px; height: 41px;">
						<a href="socialAuth.do?id=google"><img
							src="images/gmail-icon.jpg" alt="Gmail"
                                                     title="Gmail" border="0"></img></a>
					</div>
					<div>
						<c:if test="${google eq true}">
							<a href="socialAuth.do?id=google&mode=signout">Signout</a>
						</c:if>
						<c:if test="${google eq false}">
							<a href="socialAuth.do?id=google">Signin</a>
							<br />
						</c:if>
					</div>
				</td>
				<td>
					<div style="width: 48px; height: 41px;">
						<a href="socialAuth.do?id=yahoo"><img
							src="images/yahoomail_icon.jpg" alt="YahooMail" title="YahooMail"
							border="0"></img></a>
					</div>
					<div>
						<c:if test="${yahoo eq true}">
							<a href="socialAuth.do?id=yahoo&mode=signout">Signout</a>
						</c:if>
						<c:if test="${yahoo eq false}">
							<a href="socialAuth.do?id=yahoo">Signin</a>
							<br />
						</c:if>
					</div>
				</td>
				<td>
					<div style="width: 48px; height: 41px;">
						<a href="socialAuth.do?id=hotmail"><img
							src="images/hotmail.jpeg" alt="HotMail" title="HotMail"
							border="0"></img></a>
					</div>
					<div>
						<c:if test="${hotmail eq true}">
							<a href="socialAuth.do?id=hotmail&mode=signout">Signout</a>
						</c:if>
						<c:if test="${hotmail eq false}">
							<a href="socialAuth.do?id=hotmail">Signin</a>
							<br />
						</c:if>
					</div>
				</td>
				<td>
					<div style="width: 48px; height: 41px;">
						<a href="socialAuth.do?id=linkedin"><img
							src="images/linkedin.gif" alt="Linked In" title="Linked In"
							border="0"></img></a>
					</div>
					<div>
						<c:if test="${linkedin eq true}">
							<a href="socialAuth.do?id=linkedin&mode=signout">Signout</a>
						</c:if>
						<c:if test="${linkedin eq false}">
							<a href="socialAuth.do?id=linkedin">Signin</a>
							<br />
						</c:if>
					</div>
				</td>
				<td>
					<div style="width: 48px; height: 41px;">
						<a href="socialAuth.do?id=foursquare"><img
							src="images/foursquare.jpeg" alt="FourSquare" title="FourSquare"
							border="0"></img></a>
					</div>
					<div>
						<c:if test="${foursquare eq true}">
							<a href="socialAuth.do?id=foursquare&mode=signout">Signout</a>
						</c:if>
						<c:if test="${foursquare eq false}">
							<a href="socialAuth.do?id=foursquare">Signin</a>
							<br />
						</c:if>
					</div>
				</td>
				<td>
					<div style="width: 48px; height: 41px;">
						<a href="socialAuth.do?id=myspace"><img
							src="images/myspace.jpeg" alt="MySpace" title="MySpace"
							border="0"></img></a>
					</div>
					<div>
						<c:if test="${myspace eq true}">
							<a href="socialAuth.do?id=myspace&mode=signout">Signout</a>
						</c:if>
						<c:if test="${myspace eq false}">
							<a href="socialAuth.do?id=myspace">Signin</a>
							<br />
						</c:if>
					</div>
				</td>
				<td>
					<div style="width: 48px; height: 41px;">
						<a href="socialAuth.do?id=mendeley"><img
							src="images/mendeley.jpg" alt="Mendeley" title="Mendeley"
							border="0"></img></a>
					</div>
					<div>
						<c:if test="${mendeley eq true}">
							<a href="socialAuth.do?id=mendeley&mode=signout">Signout</a>
						</c:if>
						<c:if test="${mendeley eq false}">
							<a href="socialAuth.do?id=mendeley">Signin</a>
							<br />
						</c:if>
					</div>
				</td>
				<td>
					<div style="width: 48px; height: 41px;">
						<a href="socialAuth.do?id=yammer"><img src="images/yammer.jpg"
							alt="Yammer" title="Yammer" border="0"></img></a>
					</div>
					<div>
						<c:if test="${yammer eq true}">
							<a href="socialAuth.do?id=yammer&mode=signout">Signout</a>
						</c:if>
						<c:if test="${yammer eq false}">
							<a href="socialAuth.do?id=yammer">Signin</a>
							<br />
						</c:if>
					</div>
				</td>
			</tr>
		</table>
		<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />

	</div>
</div>


Index page will be look like as given below. There may be difference of CSS and images. You can add the CSS and images from the source code. ![Index Page](images/struts_index.jpg)
###Step 7. Writing the authentication action Now we develop the action that is called by the link we created in the step above. This action creates a instance of SocialAuthConfig which loads the configuration for providers. Then it creates a instance of the SocialAuthManager and calls the getAuthenticationUrl() method to find the URL to redirect to. It also saves the instance of socialauth manager in session scope. Finally the action redirects to the URL obtained from the getAuthenticationUrl() and the user sees the login page of facebook, gmail or yahoo.
Please notice that any provider will also need a URL from the application to which it will forward after successful authentication. In the sample below this URL is socialAuthSuccessAction.do which corresponds to another action that we will develop in the next step. ``` package org.brickred.actions;

import java.io.InputStream; import java.util.Map;

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.RequestUtils; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.interceptor.ServletResponseAware; import org.apache.struts2.interceptor.SessionAware; import org.apache.struts2.views.util.UrlHelper; import org.brickred.socialauth.SocialAuthConfig; import org.brickred.socialauth.SocialAuthManager;

@Results({ @Result(name = "home", location = "/index.jsp"), @Result(name = "failure", location = "/jsp/error.jsp"), @Result(name = "redirect", location = "${url}", type = "redirect") }) public class SocialAuthenticationAction implements SessionAware, ServletRequestAware, ServletResponseAware {

final Log LOG = LogFactory.getLog(SocialAuthenticationAction.class);

private Map<String, Object> userSession;
private String id;
private String mode;
private String url;
private HttpServletRequest request;
private HttpServletResponse response;

@Action(value = "/socialAuth")
public String execute() throws Exception {
	LOG.info("Given provider id :: " + id);
	SocialAuthManager manager;
	if (userSession.get("socialAuthManager") != null) {
		manager = (SocialAuthManager) userSession.get("socialAuthManager");
		if ("signout".equals(mode)) {
			manager.disconnectProvider(id);
			return "home";
		}
	} else {
		InputStream in = SocialAuthenticationAction.class.getClassLoader()
				.getResourceAsStream("oauth_consumer.properties");
		SocialAuthConfig conf = SocialAuthConfig.getDefault();
		conf.load(in);
		manager = new SocialAuthManager();
		manager.setSocialAuthConfig(conf);
		userSession.put("socialAuthManager", manager);
	}

	String returnToUrl = RequestUtils.getServletPath(request);
	
	returnToUrl = UrlHelper.buildUrl("socialAuthSuccessAction.do", request,
			response, null, null, true, true, true);
	url = manager.getAuthenticationUrl(id, returnToUrl);
	LOG.info("Redirecting to: " + url);
	if (url != null) {
		return "redirect";
	}
	return "failure";
}

@Override
public void setSession(final Map<String, Object> session) {
	userSession = session;
}

@Override
public void setServletRequest(final HttpServletRequest request) {
	this.request = request;
}

@Override
public void setServletResponse(final HttpServletResponse response) {
	this.response = response;
}

public String getId() {
	return id;
}

public void setId(final String id) {
	this.id = id;
}

public String getMode() {
	return mode;
}

public void setMode(final String mode) {
	this.mode = mode;
}

public String getUrl() {
	return url;
}

public void setUrl(final String url) {
	this.url = url;
}

}

###Step 8. Creating the success action
Now we create a success action whose path was given in above action. This action verifies the user when the external provider forwards the user back to our application. It gets the instance of the SocialAuthManager from session and calls connect() method and returns AuthProvider object. We can call various method of returned provider object to get the profile or contacts.

package org.brickred.actions;

import java.util.ArrayList; import java.util.List; import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.xwork.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.interceptor.SessionAware; import org.brickred.socialauth.AuthProvider; import org.brickred.socialauth.Contact; import org.brickred.socialauth.Profile; import org.brickred.socialauth.SocialAuthManager; import org.brickred.socialauth.util.SocialAuthUtil;

/**

  • Verifies the user when the external provider redirects back to our
  • application. It gets the instance of the requested provider from session and
  • calls verifyResponse() method which verifies the user and returns profile
  • information. After verification we call the getContactList() method to get
  • the contacts.
  • @author tarun.nagpal

*/ @Results({ @Result(name="success",location="/jsp/authSuccess.jsp"), @Result(name="failure",location="/jsp/error.jsp"), }) public class SocialAuthSuccessAction implements SessionAware,ServletRequestAware {

final Log LOG = LogFactory.getLog(this.getClass());

private Map<String, Object> userSession ;
public HttpServletRequest request;

/**
 * Displays the user profile and contacts for the given provider.
 * 
 * @return String where the action should flow
 * @throws Exception
 *             if an error occurs
 */
@Action(value="/socialAuthSuccessAction")
public String execute() throws Exception {


	SocialAuthManager manager = null;
	if (userSession.get("socialAuthManager") != null) {
		manager = (SocialAuthManager)userSession.get("socialAuthManager");
	} 
	
	if(manager!=null){
		List<Contact> contactsList = new ArrayList<Contact>();
		Profile profile = null;
		try {
			Map<String, String> paramsMap = SocialAuthUtil
					.getRequestParametersMap(request);
			AuthProvider provider = manager.connect(paramsMap);
			profile = provider.getUserProfile();
			contactsList = provider.getContactList();
			if (contactsList != null && contactsList.size() > 0) {
				for (Contact p : contactsList) {
					if (StringUtils.isEmpty(p.getFirstName())
							&& StringUtils.isEmpty(p.getLastName())) {
						p.setFirstName(p.getDisplayName());
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		request.setAttribute("profile", profile);
		request.setAttribute("contacts", contactsList);
		return "success";
	}
	return "failure";
	
}

@Override
public void setSession(Map<String, Object> session) {
	userSession = session ;
	
}

@Override
public void setServletRequest(HttpServletRequest request) {
	this.request = request; 
}

}

###Step 9. Displaying the results
Create authSuccess.jsp file under src\main\webapp\jsp directory. It will show the profile and contacts of the autheticated user from the connected provider.

<% String path = request.getContextPath(); %>

<style type="text/css"> .style1 { text-align: justify; } .sectiontableheader { background-color: #C8D7E3; color: #293D6B; font-size: 8pt; font-weight: bold; padding: 2px; } .sectiontableentry2 { background: none repeat scroll 0 0 #F7F7F7; padding: 2px; } .sectiontableentry1 { background: none repeat scroll 0 0 #FFFFF0; padding: 2px; } </style> <script> function updateStatus(){ var btn = document.getElementById('btnUpdateStatus'); btn.disabled=true; var msg = prompt("Enter your status here:"); if(msg == null || msg.length == 0){ btn.disabled=false; return false; } msg = "statusMessage="+msg; var req = new XMLHttpRequest(); req.open("POST", "<%=request.getContextPath()%> /socialAuthUpdateStatusAction.do"); req.setRequestHeader("Accept", "text/xml"); req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); req.setRequestHeader("Content-length", msg.length); req.setRequestHeader("Connection", "close"); req.onreadystatechange = function() { if (req.readyState == 4) { if (req.responseText.length > 0) { alert(req.responseText); btn.disabled = false; } } }; req.send(msg); } function uploadDone(name) { var frame = getFrameByName(name); if (frame) { var res = frame.document.getElementsByTagName("body")[0].innerHTML; if (res.length) { alert(res); document.getElementById("upButton").disabled = false; document.getElementById("message").value = ""; document.getElementById("imageFile").value = ""; } } } function getFrameByName(name) { for ( var i = 0; i < frames.length; i++) if (frames[i].name == name) return frames[i]; return null; } </script>

<%@page import="org.brickred.socialauth.Profile,java.util.*;"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="s" uri="/struts-tags"%> <%@ page isELIgnored="false"%>

<div id="text">
	<h2 align="center">Authentication has been successful.</h2>
	<br />
	<div align="center">
		<a href="index.jsp">Back</a>
	</div>
	<br />
	<h3 align="center">Profile Information</h3>
	<table cellspacing="1" cellspacing="4" border="0" bgcolor="e5e5e5"
		width="60%" align="center">
		<tr class="sectiontableheader">
			<th>Profile Field</th>
			<th>Value</th>
		</tr>
		<tr class="sectiontableentry1">
			<td>Email:</td>
			<td><c:out value="${profile.email}" /></td>
		</tr>
		<tr class="sectiontableentry2">
			<td>First Name:</td>
			<td><c:out value="${profile.firstName}" /></td>
		</tr>
		<tr class="sectiontableentry1">
			<td>Last Name:</td>
			<td><c:out value="${profile.lastName}" /></td>
		</tr>
		<tr class="sectiontableentry2">
			<td>Country:</td>
			<td><c:out value="${profile.country}" /></td>
		</tr>
		<tr class="sectiontableentry1">
			<td>Language:</td>
			<td><c:out value="${profile.language}" /></td>
		</tr>
		<tr class="sectiontableentry2">
			<td>Full Name:</td>
			<td><c:out value="${profile.fullName}" /></td>
		</tr>
		<tr class="sectiontableentry1">
			<td>Display Name:</td>
			<td><c:out value="${profile.displayName}" /></td>
		</tr>
		<tr class="sectiontableentry2">
			<td>DOB:</td>
			<td><c:out value="${profile.dob}" /></td>
		</tr>
		<tr class="sectiontableentry1">
			<td>Gender:</td>
			<td><c:out value="${profile.gender}" /></td>
		</tr>
		<tr class="sectiontableentry2">
			<td>Location:</td>
			<td><c:out value="${profile.location}" /></td>
		</tr>
		<tr class="sectiontableentry1">
			<td>Profile Image:</td>
			<td><c:if test="${profile.profileImageURL != null}">
					<img src='<c:out value="${profile.profileImageURL}"/>' />
				</c:if></td>
		</tr>
		<tr class="sectiontableentry2">
			<td>Update status:</td>
			<td><input type="button" value="Click to Update Status"
				onclick="updateStatus();" id="btnUpdateStatus" /></td>
		</tr>
	</table>
	<br />
	<h3 align="center">Upload Status with Image</h3>
	<s:form action="socialAuthUploadPhotoAction.do"
		enctype="multipart/form-data" method="post" target="hidden_upload">
		<table cellspacing="1" cellspacing="4" border="0" bgcolor="e5e5e5"
			align="center" width="60%">
			<tr class="sectiontableheader">
				<th colspan="2">This is only for Facebook & Twitter</th>
			</tr>
			<tr class="sectiontableentry1">
				<td>Status:</td>
				<td><s:textfield name="statusMessage" id="statusMessage" /></td>
			</tr>
			<tr class="sectiontableentry2">
				<td>Select File:</td>
				<td><s:file name="imageFile" id="imageFile" /> <span
					style="font-size: 11px; font-weight: bold;">(JPG, JPEG,
						PNG, GIF only.)</span></td>
			</tr>
			<tr class="sectiontableentry2">
				<td colspan="2" align="center"><s:submit name="upButton"
						id="upButton" onclick="this.disabled=true;" /></td>
			</tr>
		</table>
	</s:form>
	<IFRAME id="hidden_upload" name="hidden_upload" src=''
		onLoad='uploadDone("hidden_upload")'
		style="width: 0; height: 0; border: 0px solid #fff"></IFRAME>
	<h3 align="center">Contact Details</h3>
	<table cellspacing="1" cellspacing="4" border="0" bgcolor="e5e5e5"
		align="center" width="60%">
		<tr class="sectiontableheader">
			<th width="15%">Name</th>
			<th>Email</th>
			<th>Profile URL</th>
		</tr>
		<c:forEach var="contact" items="${contacts}" varStatus="index">
			<tr
				class='<c:if test="${index.count % 2 == 0}">

sectiontableentry2</c:if> <c:if test="${index.count % 2 != 0}">sectiontableentry1</c:if>'>

<c:out value="${contact.firstName}" /> <c:out value="${contact.lastName}" /> <c:out value="${contact.email}" /> <c:out value="${contact.profileUrl}" /> </c:forEach>








<br/>
It'll be look like this.<br/>
![Success Page](images/struts_success.jpg)
<br/>
As you can see this jsp also has an option to update status and upload image with status message. Action for updating status and uploading image is given in next steps.

###Step 10. Action for Updating Status
You can see the java script function "updateStatus()" in the jsp creates in Step 9. This java script function makes a AJAX call to update status and call the following action. This action use updateStatus() function of AuthProvider class of SocialAuth library.

package org.brickred.actions;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.interceptor.SessionAware; import org.brickred.socialauth.AuthProvider; import org.brickred.socialauth.SocialAuthManager; import org.brickred.socialauth.exception.SocialAuthException;

/**

  • This is for updating status. After verification we call the updateStatus()
  • method to update status on that provider.
  • @author tarun.nagpal

*/ @Results({ @Result(name="success",location="/jsp/statusSuccess.jsp"), @Result(name="failure",location="/jsp/statusSuccess.jsp"), }) public class SocialAuthUpdateStatusAction implements SessionAware,ServletRequestAware {

final Log LOG = LogFactory.getLog(this.getClass());

private Map<String, Object> userSession ;
private HttpServletRequest request;
private String statusMessage;

/**
 * Update status for the given provider.
 * 
 * @return String where the action should flow
 * @throws Exception
 *             if an error occurs
 */
@Action(value="/socialAuthUpdateStatusAction")
public String execute() throws Exception {
	
	LOG.info("Status Message :: "+statusMessage);
	if (statusMessage == null || statusMessage.trim().length() == 0) {
		request.setAttribute("Message", "Status can't be left blank.");
		return "failure";
	}
	
	SocialAuthManager manager = null;
	if (userSession.get("socialAuthManager") != null) {
		manager = (SocialAuthManager)userSession.get("socialAuthManager");
	} 
	AuthProvider provider = null;
	if(manager!=null){
		provider = manager.getCurrentAuthProvider();
	}
	if (provider != null) {
		try {
			provider.updateStatus(statusMessage);
			request.setAttribute("Message", "Status Updated successfully");
			return "success";
		} catch (SocialAuthException e) {
			request.setAttribute("Message", e.getMessage());
			LOG.error(e);
		}
	}
	return "failure";
	
}

@Override
public void setSession(Map<String, Object> session) {
	userSession = session ;
	
}

@Override
public void setServletRequest(HttpServletRequest request) {
	this.request = request; 
}

public String getStatusMessage() {
	return statusMessage;
}

public void setStatusMessage(String statusMessage) {
	this.statusMessage = statusMessage;
}

}


###Step 11. Create statusSuccess.jsp file.
Create statusSuccess.jsp file in src\main\webapp\jsp directory. This jsp returns the message of status update success or failure from the above action.

<% if(request.getAttribute("Message")!=null){ out.print(request.getAttribute("Message")); }%>

##Step 12. Create error.jsp
Create error.jsp file in src\main\webapp\jsp directory. 
<title>Error page</title>

Oops an error had occurred..



Go back ```

##Step 13. Create action to Upload photo with status message. As you can see in there is a form to upload image in the jsp file creates in Step 9. This form call this action to upload image, which upload photo on providers using SocialAuth library.

package org.brickred.actions;

import java.io.File;
import java.io.FileInputStream;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.SessionAware;
import org.brickred.socialauth.AuthProvider;
import org.brickred.socialauth.SocialAuthManager;
import org.brickred.socialauth.exception.SocialAuthException;

/**
 * This is for updating status with image.
 * 
 * @author tarun.nagpal
 *
 */
@Results({
    	@Result(name="success",location="/jsp/statusSuccess.jsp"),
		@Result(name="failure",location="/jsp/statusSuccess.jsp"),
	})
@InterceptorRefs({
	  @InterceptorRef(value="fileUpload", 
          params={"AllowedTypes", " image/PNG,image/png,image/GIF, image/gif, image/JPEG, 
               image/JPG, image/jpg,image/jpeg"}),
	  @InterceptorRef("basicStack")
	})
public class SocialAuthUploadPhotoAction implements SessionAware,ServletRequestAware {

	final Log LOG = LogFactory.getLog(this.getClass());
	
	private Map<String, Object> userSession ;
	private HttpServletRequest request;
	private File imageFile;
	private String imageFileContentType;
	private String imageFileFileName;
	private String statusMessage;
	
	/**
	 * Update status for the given provider.
	 * 
	 * @return String where the action should flow
	 * @throws Exception
	 *             if an error occurs
	 */
	@Action(value="/socialAuthUploadPhotoAction")
	public String execute() throws Exception {

		
		SocialAuthManager manager = null;
		if (userSession.get("socialAuthManager") != null) {
			manager = (SocialAuthManager)userSession.get("socialAuthManager");
		} 
		AuthProvider provider = null;
		if(manager!=null){
			provider = manager.getCurrentAuthProvider();
		}
		if (provider != null) {
			try {
				provider.uploadImage(statusMessage,
						imageFileFileName, new FileInputStream(imageFile));
				request.setAttribute("Message", "Status Updated successfully");
				return "success";
			} catch (SocialAuthException e) {
				request.setAttribute("Message", e.getMessage());
				e.printStackTrace();
			}
		}
		return "failure";
		
	}

	@Override
	public void setSession(Map<String, Object> session) {
		userSession = session ;
		
	}
	
	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request; 
	}

	public String getStatusMessage() {
		return statusMessage;
	}

	public void setStatusMessage(String statusMessage) {
		this.statusMessage = statusMessage;
	}

	public File getImageFile() {
		return imageFile;
	}

	public void setImageFile(File imageFile) {
		this.imageFile = imageFile;
	}

	public String getImageFileContentType() {
		return imageFileContentType;
	}

	public void setImageFileContentType(String imageFileContentType) {
		this.imageFileContentType = imageFileContentType;
	}

	public String getImageFileFileName() {
		return imageFileFileName;
	}

	public void setImageFileFileName(String imageFileFileName) {
		this.imageFileFileName = imageFileFileName;
	}
}

###Conclusion

You can get the entire source code of the sample by browsing the source code or from socialauth-java-sdk-4.2.zip. Hope this guide would have been of help. If you have any questions, please file an issue.