Showing posts with label struts2. Show all posts
Showing posts with label struts2. Show all posts

Friday, May 30, 2008

Authenticating Struts2 Applications using Interceptor

When I needed to introduce authentication into my existing application, I tried searching for an Interceptor written and shared by someone on internet. And as I guessed, I found some really helpful pieces of code, ready-to-use.

As I closely observed them, I found that they were implemented in almost similar fashion. What was common in both of them was the fact that 'interceptor was authenticating the user on login attempt'. I somehow wasn't comfortable with the idea of putting business logic in Interceptor. I thought, when a user is trying to log on to the system, a Login action should be called to Log the user into the system. I believe the interceptor should only keep a watch on the requests rather than processing them. Let request-processing be done by Actions.

So I wrote my own AuthenticationInterceptor.

  • It doesn't authenticate the user by itself, but just allows the 'LoginAttempt Request' being submitted to 'Login Action'.
  • When an un-authenticated user is attempting to invoke any action, it redirects request to Login page.
  • It just 'observes' all requests from an authenticated user.

I believe the code is self explanatory. Let me know if anything is not clear.

/**
* @author Rushikesh Thakkar
*/

@SuppressWarnings({"serial", "unchecked"})
public class AuthenticationInterceptor extends AbstractInterceptor {

private Map request, session;
public String intercept (ActionInvocation invocation) throws Exception {

session = invocation.getInvocationContext().getSession();
request = invocation.getInvocationContext().getParameters();

User user = (User) session.get(Constants.USER_KEY);

// CHECK IF THE USER IS ATTEMPTING TO LOGIN
boolean loginAttempt = request.get(Constants.LOGIN_ATTEMPT) == null ? false : true;

// CHECK IF THE USER IS ATTEMPTING TO LOGOUT
boolean logoutAttempt = request.get(Constants.LOGOUT_ATTEMPT) == null ? false : true;

System.out.println("__loginAttempt: " + loginAttempt);
System.out.println("__logoutAttempt: " + logoutAttempt);

if (user != null) { // USER IS ALREADY LOGGED IN
nbsp;if (!loginAttempt && logoutAttempt) // USER IS TRYING TO LOGOUT
return invocation.invoke();
else // USER IS TRYING TO PERFORM SOME BUSINESS-ACTION
return invocation.invoke();

} else { // USER IS NOT LOGGED IN
System.out.println("#12");
if (loginAttempt) { // USER IS TRYING TO LOGIN
return invocation.invoke();
} else // USER IS TRYING TO PERFORM SOME BUSINESS-ACTION
return "show-login";
}
}
}


Disclaimer: The code may not be perfect. Please test is thoroughly before using, and let me know if any correction is needed.

Tuesday, April 29, 2008

Showing dynamic User Interface using Struts2

The main purpose for writing this post is to help understand the compilation process of a Struts2 JSP, and to highlight how useful the OGNL expression can be.

I had to make a form that would display different sets of text-fields in different situations. So I did something like what follows:

Action:
public class ShowDynamicForm extends ActionSupport {

private List fields = new ArrayList (); //will be iterated in the following JSP

public String execute() throws Exception {
//The list: 'fields' can be populated from database depending on requirement
fields.add("name");
fields.add("number");
fields.add("class");
fields.add("result");

return SUCCESS;
}

public List getFields() {
return fields;
}
public void setFields(List fields) {
this.fields = fields;
}
}

JSP: The jsp is the most important artifact to understand. It mainly does the following:
- Iterates the list (populated by ShowDynamicForm action) and
- Dynamically renders labels and text-boxes for the required fields using OGNL expressions.
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<%-- author: Rushikesh Thakkar --%>

<html>
<body>
<s:i18n name="labels">
<table border="0" bordercolor="gray" cellpadding="5" cellspacing="0">
<tr>

<s:iterator value="fields" status="status" id="field">

<td><s:text name="%{fields[#status.index]}"/></td>
<td><s:textfield name="field.%{fields[#status.index]}" theme="simple" value="%{#status.index}" /></td>
<s:if test="#status.even">
</tr>
</s:if>
</s:iterator>

</table>

</s:i18n>
</body>
</html>

Explanation: First, the OGNL expressions are evaluated in the JSP. This helps
<s:text /> and <s:textfield /> get values for their attributes 'name' and 'value'. So in the first pass
<s:text name="%{fields[#status.index]}"/> becomes
<s:text name="name"></s:text> and similarly for
<s:textfield name="field.%{fields[#status.index]}" theme="simple" value="%{#status.index}" /> for entire itearation.
And then its simple to understand. I am using the following labels.properties file to provide values for
<s:text /> tag.

labels.properties:
name=Student Name
number=Roll No.
class=Class
result:Result

Struts2 File Download Problem

File download has been explained pretty clearly in Struts2 documentation site. I exactly followed the steps given. But I was not able to download a file. Though I didn't get any error, nothing was happening either. I wasted an entire day trying to figure out what the problem was with my code, and then I found out that I was using 'ajax' theme for the submit button that was supposed to submit download request. When I removed it, it started working perfectly fine.

So
do not use
theme='ajax' in <s:submit /> or <s:a/>.