Sessions in struts2 application
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>
How many sessions can be managed by an Java Application in Struts 2?
Limit is the size of your computers physical memory.you dont store dynamic values in session because someone can modify them in the meanwhile , so store only those values in session which represent any user specific data or static values (i.e. which are not going to be changed while session exists).
Note : static here is not static keyword .
Session in struts2 application not working
Try the code below
@SkipValidation
public String logout(){
...
}
And i also i want that when back button is pressed it should not redirect to logged in page of user.
<action name="logout" class="org.entity.LoginAction" method="logout">
<result type="redirect">/</result>
</action>
Checking a session value in Struts 2 web application
@rickgaurav for your 1st question. make a login action like this
<action name="login_action" class="loginAction class">
<result name="success" type="chain">welcomeAction</result>
<result name="input">/index.jsp</result>
<result name="error">/index.jsp</result>
</action>
wher index.jsp is your login page
and in login interceptor first make a session map in which your session attribute will be store
Map<String, Object> sessionAttributes = invocation
.getInvocationContext().getSession();
after that check using this condition
if (sessionAttributes == null
|| sessionAttributes.get("userName") == null
|| sessionAttributes.get("userName").equals("")) {
return "login";
}else{
if (!((String) sessionAttributes.get("userName")).equals(null)){
return invocation.invoke();
}else{
return "login";
}
for your 2nd question assume you are calling a welcomeAction to go to the welcome.jsp page
so you can add action like this
<action name="welcomeAction" class="class">
<interceptor-ref name="logininterceptor"></interceptor-ref>
<result name="login" type="chain">loginaction</result>
<result name="success" >/welcome.jsp</result>
</action>
hope so this will work for you
Sharing session between Servlets and Struts 2 application issue
Please try using SessionAware interface implementation for this . For more help see below link.
http://www.codejava.net/frameworks/struts/working-with-httpsession-in-struts2-a-login-example
Access all User Session in Struts 2
I think HttpSessionBindingListener
is what are you looking for.
I won't write down the complete code, just suggest you a way you can do it:
You can add a static field (Map) to your User class (DTO)
where you will store all active sessions of users
. :
e.g private static Map<User, HttpSession> usersSessions= new HashMap<User, HttpSession>();
Then make User class
implemets HttpSessionBindingListener
. This way you can specify valueBound(HttpSessionBindingEvent event)
method in which you can grab actually created session
and put it into your usersSessions
like this :
usersSessions.put(this, event.getSession());
In valueUnbound(HttpSessionBindingEvent event)
method then :
usersSessions.remove(this);
to remove users session
after logout
.
This way you have Map
of all of your active sessions
also with information to which user it belongs to. IMO you can figure out your other problems easily with this.
Can two different struts Web application share same session and can I utilize the same for single sign on
application, request, session and page scoped objects are only specific to one application.
Session variable is not the solution for your problem.
Let your Single Sign-On Application send those variables to both the applications as custom attributes. Just like the authenticated user name.
Or use a Database table to share the session info.
Note: You will run into race conditions unless app2 access is initiated from app1.
struts2 creating session objects, why and when?
Here is an answer from the Cayenne perspective. By default WebApplicationContextFilter lazily creates a session-bound ObjectContext for each request that the filter matches. This creates an HttpSession of course.
So one solution would be to reduce the filter mapping from "/*" to a more specific URL that corresponds to authenticated pages. Then Cayenne filter will not be called for anonymous users.
If this can't be done, create your own version of WebApplicationContextFilter (after all WebApplicationContextFilter is just an example of how Cayenne can be bootstrapped in the app, so check its source, and create something similar for yourself). Your own filter can implement some logic that skips ObjectContext (and session) creation for anonymous.
How to track the session for all URLs in Struts 2
If all your application pages have to be accessed by authenticated user, then you have to redirect the user to login
page in any cases that there is no user
attribute in his/her session.
The problem is in your if
conditions. I Don't know what are you doing in your LogoutAction
, but if it's invalidation user session by removing user
attribute from his/her session, then your if
block should be as this:
public String intercept(ActionInvocation ai) throws Exception {
// TODO Auto-generated method stub
System.out.println("inside the interceptor()......new");
Map session = ai.getInvocationContext().getSession();
if ((session.get("user") != null) ||
((session.get("user") == null) && (ai.getAction() instanceof LoginAction)) {
return ai.invoke();
} else {
return "login";
}
}
This way, user has no choice if he has not passed the login action first. The LogoutAction
action is just any other action in your application and could be called in cases where there is user
attribute in user session.
Your original if
statements checked this condition just in cases where the requested action is logout.
Related Topics
Why Do We Have to Override the Equals() Method in Java
Selenium Webdriver: Wait for Complex Page with JavaScript to Load
What Are the Main Uses of Yield(), and How Does It Differ from Join() and Interrupt()
How to Handle Simultaneous Key Presses in Java
Does Java Support Inner/Local/Sub Methods
How to Create a Class Literal of a Known Type: Class<List<String>>
Compilation Error: Identifier Expected
Hibernate Sessionfactory VS. JPA Entitymanagerfactory
How to Call Custom Database Functions with Hibernate
Spring Data: Override Save Method
When Is It Ok to Catch Nullpointerexception
How to Copy Java Collections List
Cannot Create Jdbc Driver of Class ' ' for Connect Url 'Null':I Do Not Understand This Exception