I have the following piece of code in my program and I am running SonarQube 5 for code quality check on it after integrating it with Maven.
However, Sonar is asking to Remove this useless assignment to local variable "session".
#RequestMapping(value = "/logoff", method = RequestMethod.GET)
public String getLogoffPage(HttpServletRequest request, HttpServletResponse response) {
logger.info(" Before Log Offf........ " + request.getSession().getId() );
HttpSession session =request.getSession(true);
request.getSession().invalidate();
myApplication.logout();
SecurityContextHolder.clearContext();
session=null;
return "login";
}
Under the assumption that the question is "why":
What do you actually do with session? Nothing.
HttpSession session =request.getSession(true); // session assigned
request.getSession().invalidate(); // session NOT used
myApplication.logout();
SecurityContextHolder.clearContext();
session=null; // session re-assigned
Perhaps you meant this?
HttpSession session =request.getSession(true);
session.invalidate();
myApplication.logout();
SecurityContextHolder.clearContext();
BTW, I've dropped session = null since there's no reason in Java (C would be another matter) to do that.
Of course, the code could be even cleaner:
request.getSession().invalidate();
myApplication.logout();
SecurityContextHolder.clearContext();
This variable is local and so when you reach the return statement it won't be accessible. As it is not read after the assignement the variable is considered Dead.
If you assign anything to a local variable and do not make use of it this is a useless instruction and thus should be removed.
Setting the variable to null is pretty much useless and in fact may be preventing the JVM to work on some optimization.
Related
I am facing very strange problem while developing JavaEE WEB Application.
Even after invalidating the HttpSession using session.invalidate();, I am not getting session null. There is a case where I have one statement in execution like below after invalidating session.
if (null != session && null != session.getAttribute("loginToken")){
//do something
}
I am not getting session null here so second condition will try to execute. And hence session is not null, so I am getting IllegalStateException - session is already invalidated. But why session is not null after invalidating it?? :(
Calling session.invalidate() removes the session from the registry. Calling getSession(false) afterwards will return null (note that getSession() or getSession(true) will create a new session in this case, see HttpServletRequest API). Calling invalidate() will also remove all session attributes bound to the session. However if your code still has references to the session or any of its attributes then these will still be accessible:
// create session if none exists (default) and obtain reference
HttpSession session = request.getSession();
// add a session attribute
session.setAttribute("lollypop", "it's my party");
// obtain reference to session attribute
Object lollypop = session.getAttribute("lollypop");
// print session ID and attribute
System.out.println(session.getId());
System.out.println(lollypop);
session.invalidate();
// session invalidated but reference to it still exists
if (session == null) {
System.out.println("This will never happen!");
}
// print ID from invalidated session and previously obtained attribute (will be same as before)
System.out.println(session.getId());
System.out.println(lollypop);
// print 'null' (create=false makes sure no new session is created)
System.out.println(request.getSession(false));
Example output:
1k47acjdelzeinpcbtczf2o9t
it's my party
1k47acjdelzeinpcbtczf2o9t
it's my party
null
So far for the explanation. To solve your problem you should do:
HttpSession existingSession = request.getSession(false);
if (existingSession != null && existingSession.getAttribute("loginToken") != null){
//do something
}
The invalidate method does the following (from API):
Invalidates this session then unbinds any objects bound to it.
It says nothing about the HttpSession-object itself, but invalidates the session's variables. If you call a method of a class, it is impossible for the object to be null after that method call. If your session should be null afterwards, the method must include a line that looks something like: this = null; which would not be possible. Throwing an exception for an invalidated session is the prefered way to do it.
Try passing false as the parameter to the getSession(boolean) . This will give back a session if it exists or else it will return null.
HttpSession session = request.getSession(false);
if(session==null || !request.isRequestedSessionIdValid() )
{
//comes here when session is invalid.
}
I'm using the java servlet API in tomcat.
I save in a hash table the username and the httpsession with the attribute username and I would like to know if there is a way to check if the httpsession is valid.
I've tried:
try {
String user = httpSession.getAttribute("username")
return "is valid";
} catch (IllegalStateException e) {
return "is not valid";
}
What can I do if I don't want that a "logged" user connect from more than one place? If I control only if I create a new session, I can't know if he was connected already with another session.
No need to store the httpSession in your own hash.
Look at the API for the HttpServletRequest. If you look at method getSession(Boolean x) (pass false so it doesn't create a new session) will determine if the session is valid.
Here is an example
public void doGet(HttpServletRequest req, HttpServletResponse res) {
HttpSession session = req.getSession(false);
if (session == null) {
//valid session doesn't exist
//do something like send the user to a login screen
}
if (session.getAttribute("username") == null) {
//no username in session
//user probably hasn't logged in properly
}
//now let's pretend to log the user out for good measure
session.invalidate();
}
On a side note, If I read your question properly and you are storing the information in your own map, you need to be careful that you don't create a memory leak and are clearing the entries out of the hash table yourself.
I agree with Sean. I will add that a good practice for this type of checking is to use a Filter
See here Servlet Filter
Just take the code Sean have written and put it in a Filter instead. Define you filter in the web.xml and every time a request come in, the filter will execute.
This way you can validate if the user is auth. without cluttering your servlet code.
Rather than checking if a saved session is valid, you should be looking at the HttpServletRequest on your servlet, and checking isRequestedSessionIdValid() on that. When working in servlets you can always get Session from the Request, rather than saving it to a hash table.
I'm new to jsf and I've read that a session can be destroyed
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) fc.getExternalContext().getSession(false);
fc.getExternalContext().getSessionMap().clear();
session.invalidate();
My problem ist, after doing that the session is still active, with the following bean :
com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap
Do you have an idea?
That's just a new session. To test it yourself, check the value of HttpSession#getId() during the request before and after invalidate. It should be different.
Unrelated to the concrete question, clearing the session map is unnecessary whenever you call invalidate(). The session map will be trashed anyway. Also note that getSession(false) can potentially return null and you'd like to add an extra check to avoid NullPointerException. Or just use getSession(true) instead.
This question already has answers here:
How do servlets work? Instantiation, sessions, shared variables and multithreading
(8 answers)
Closed 5 years ago.
So far I understand Httpsession concepts in Java.
HttpSession ses = req.getSession(true);
will create a session object, according to the request.
setAttribute("String", object);
will, bind the 'String', and value with the Session object.
getAttribute("String");
will return an object associated with the string, specified.
What I am not able to understand is: I am creating a session object like
HttpSession ses = req.getSession(true);
and setting a name for it by calling setAttribute("String", object);.
Here, This code resides inside the server. For every person, when he tries to login the same code in the server will be executed. setAttribute("String", object); in this method the string value is a constant one. So, each session object created will be binded by the same string which I have provided. When I try to retrieve the string to validate his session or while logout action taken the getAttribute("String"); ll return the same constant string value(Am I right!!?? Actually I don't know, I'm just thinking of its logic of execution). Then, how can I be able to invalidate.
I saw this type of illustration in all of the tutorials on the WEB. Is it the actual way to set that attribute? Or, real application developers will give a variable in the "String" field to set it dynamically
(ie. session.setAttribut(userName, userName); //Setting the String Dynamically.. I dono is it right or not.)
And my final question is
WebContext ctx = WebContextFactory.get();
request = ctx.getHttpServletRequest();
What do the two lines above do? What will be stored in ctx & request?
HttpSession ses = req.getSession(true); will creates new session means. What value stored in ses.
Some [random] precisions:
You don't need login/logout mechanisms in order to have sessions.
In java servlets, HTTP sessions are tracked using two mechanisms, HTTP cookie (the most commonly used) or URL rewriting (to support browsers without cookies or with cookies disabled). Using only cookies is simple, you don't have to do anything special. For URL re-writing, you need to modify all URLs pointing back to your servlets/filters.
Each time you call request.getSession(true), the HttpRequest object will be inspected in order to find a session ID encoded either in a cookie OR/AND in the URL path parameter (what's following a semi-colon). If the session ID cannot be found, a new session will be created by the servlet container (i.e. the server).
The session ID is added to the response as a Cookie. If you want to support URL re-writing also, the links in your HTML documents should be modified using the response.encodeURL() method. Calling request.getSession(false) or simply request.getSession() will return null in the event the session ID is not found or the session ID refers to an invalid session.
There is a single HTTP session by visit, as Java session cookies are not stored permanently in the browser. So sessions object are not shared between clients. Each user has his own private session.
Sessions are destroyed automatically if not used for a given time. The time-out value can be configured in the web.xml file.
A given session can be explicitly invalidated using the invalidate() method.
When people are talking about JSESSIONID, they are referring to the standard name of the HTTP cookie used to do session-tracking in Java.
I suggest you read a tutorial on Java sessions. Each user gets a different HttpSession object, based on a JSESSIONID request/response parameter that the Java web server sends to the browser. So every user can have an attribute with the same name, and the value stored for this attribute will be different for all users.
Also, WebContextFactory and WebContext are DWR classes that provide an easy way to get the servlet parameters.
As I understand it, your concerns are about separation of the different users when storing things in the HttpSession.
The servlet container (for example Tomcat) takes care of this utilizing its JSESSIONID.
The story goes like this :
User first logs onto website.
Servlet container sets a COOKIE on
the user's browser, storing a UNIQUE
jsessionId.
Every time the user hits the
website, the JSESSIONID cookie is
sent back.
The servlet container uses this to
keep track of who is who.
Likewise, this is how it keeps track
of the separation of data. Every
user has their own bucket of
objects uniquely identified by the
JSESSIONID.
Hopefully that (at least partially) answers your question.
Cheers
Your basic servlet is going to look like
public class MyServlet{
public doGet(HttpServletRequest req, HttpServletResponse res){
//Parameter true:
// create session if one does not exist. session should never be null
//Parameter false:
// return null if there is no session, used on pages where you want to
// force a user to already have a session or be logged in
//only need to use one of the two getSession() options here.
//Just showing both for this test
HttpSession sess = req.getSession(true);
HttpSession sess2 = req.getSession(false);
//set an Attribute in the request. This can be used to pass new values
//to a forward or to a JSP
req.setAttribute("myVar", "Hello World");
}
}
There is no need to set any attribute names for your session that is already done. As others have suggested in other answers, use cookies or URL re-writing to store the sessionID for you.
When you are dealing with the DWR WebContext, it is simply doing the same thing as above, just normally the Request object isn't passed into the method, so you use the WebContext to get that request for you
public class DWRClass {
public doSomething(){
WebContext ctx = WebContextFactory.get();
HttpServletRequest req = ctx.getHttpServletRequest();
HttpSession sess = req.getSession(); //no parameter is the same as passing true
//Lets set another attribute for a forward or JSP to use
ArrayList<Boolean> flags = new ArrayList<Boolean>();
req.setAttribute("listOfNames", flags);
}
}
How to get Hibernate session inside a Hibernate Interceptor?
I'm trying to use Hibernate to enforce data access by organization id transparently.
I have set a global Filter to filter all queries by organization id.
Now, I need to use an Entity interceptor to set Organizational Id on all Entities before Save/Update.
The organization id comes from HttpSession
I've set Organizational Id as a Filter property in Hibernate session which i want to retrieve inside my interceptor and use for all Inserts and Updates as well.
The problem is i dont seem to have access to Session inside the Interceptor. Any workarounds for this?
You can, but I would use a simple POJO just to keep things cleanly separated. Keep in mind that the value stored in the singleton will only be accessible by the same thread that handled the servlet request, so if you're doing any asynch, you will need to account for that. Here's a super basic impl:
public class OrgId {
public static ThreadLocal<Integer> orgId = new ThreadLocal<Integer>();
}
Since the Organizational Id is resident in the session, you could set the value of the ThreadLocal in an early servlet filter like this (not much error checking):
public class OrgIdFilter implements Filter {
public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain) throws java.io.IOException, javax.servlet.ServletException {
int orgId = 0;
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpSession session = req.getSession();
orgId = Integer.parseInt(session.getAttribute("OrganizationalIdAttr"));
try {
OrgId.orgId.set(orgId);
filterChain.doFilter(servletRequest, servletresponse);
} finally {
OrgId.orgId.set(null); // Important to clear after request !!
}
}
}
This assumes that the orgId is in the session when the filter is called, but if not, you get the idea....
Then in your interceptor (or pretty much anywhere) you can get the thread's current orgId with:
OrgId.orgId.get(); // Might be null.....
A potential snafu here is that all these components (filter, OrgId and interceptor) need to be loaded by the same class loader to ensure that the OrgId class is effectively a singleton, otherwise, with multiple instances of the ThreadLocal hanging around it won't work consistently, or at all. Needless to say, all this needs to be happening in the same VM.
I am not sure if this is the cleanest way to solve this problem, but it does get you your orgId where you need it.
If all you need is the Organizational Id, you could put it in a static ThreadLocal and then access it in the interceptor.
On the other hand if you are dead set on getting the session, and this depends on what your environment is, you could ditch the interceptor and use an org.hibernate.event.FlushEntityEventListener which seems to be more along the lines of what you need anyways. You can get the session like this (rough pseudo code):
FlushEntityEventListener.onFlushEntity(FlushEntityEvent event)
EntityEvent entityEvent = event.getEntityEntry();
EntityPersister persister = entityEvent.getPersister();
SessionFactoryImplementor sessionFactoryImplor = persister.getFactory();
Session session = sessionFactoryImplor.getCurrentSession();
From the Hibernate 3 On Line Docs: The event system can be used in addition or as a replacement for interceptors.
When you create your Interceptor, if you can provide it with a reference to the SessionFactory, you can use SessionFactory#getCurrentSession
Interceptor can be made BeanFactoryAware and SessionFactory can be obtained using the bean factory from which current session can be obtained.
Since it seemed like a bad design because of the circular dependency and making the Interceptor aware of Spring container, i used ThreadLocal as suggested by Nicholas