There are a few problems with the code you currently have.
- You should use an Interceptor to enforce that the user is logged in, rather than trying to enforce it in the JSP. JSP should only be for presentation, not for flow control.
- You should avoid scriptlets (blocks of code) in JSP. That was deprecated a really long time ago and is widely considered to be a very poor practice in an MVC application.
- You can access session values in your JSP directly. You do not need to implement the
SessionAware
interface in your action unless you need access to the session inside of the action itself. - You should redirect the user to a login action, not directly to a JSP page, otherwise you are bypassing the Struts2 framework and losing out on the benefits of using the framework.
Login Example
Below is some example code for creating a basic login system using the Struts2 framework.
Login Required
This part is optional, but in general, not all pages in a web application will require the user to be logged in. Therefore, let’s create an interface called LoginRequired
. Any action that implements this marker interface will redirect to the login page if the user is not already logged in.
Note: You can use an annotation instead, if you prefer, but for this example I will use the interface.
public interface LoginRequired {}
The Interceptor
The interceptor will handle forcing the user to login for any requested action which implements the LoginRequired
interface.
public class LoginInterceptor extends AbstractInterceptor {
@Override
public String intercept(final ActionInvocation invocation) throws Exception {
Map<String, Object> session = ActionContext.getContext().getSession();
// sb: feel free to change this to some other type of an object which
// represents that the user is logged in. for this example, I am using
// an integer which would probably represent a primary key that I would
// look the user up by with Hibernate or some other mechanism.
Integer userId = (Integer) session.get("userId");
// sb: if the user is already signed-in, then let the request through.
if (userId != null) {
return invocation.invoke();
}
Object action = invocation.getAction();
// sb: if the action doesn't require sign-in, then let it through.
if (!(action instanceof LoginRequired)) {
return invocation.invoke();
}
// sb: if this request does require login and the current action is
// not the login action, then redirect the user
if (!(action instanceof LoginAction)) {
return "loginRedirect";
}
// sb: they either requested the login page or are submitting their
// login now, let it through
return invocation.invoke();
}
}
You will also need a LoginAction
which displays and processes the login page and a LogoutAction
which invalidates or clears the session.
The Configuration
You will need to add the interceptor to your stack and also create a global result mapping for “loginRedirect”.
<interceptors>
<interceptor name="login" class="your.package.LoginInterceptor"/>
<!-- sb: you need to configure all of your interceptors here. i'm only
listing the one we created for this example. -->
<interceptor-stack name="yourStack">
...
<interceptor-ref name="login"/>
...
</interceptor-stack>
</interceptors>
<global-results>
<!-- sb: make this the path to your login action.
this could also be a redirectAction type. -->
<result name="loginRedirect" type="redirect">/login</url>
</global-results>