Suppose I have a servlet that processes logins. When the login is successful the user will create a session for this user. Then redirects to a homepage.
Let's say the homepage has a link "view all". This link calls a servlet, viewall.html to process all the data from the database then redirect to a jsp page (viewall.jsp) that will display the data from the servlet.
Somewhere from the servlet viewall.html to the jsp viewall.jsp, I would like to have code that looks like this:
if (session attribute user is null) {
// redirect to the login page
} else {
// if in the servlet, retrieve the data from the database
// if in the jsp, display the data
}
What is the better way to check if there is a session, on the servlet or the jsp? Note I know about filters, let's say the project can't use filters.
It is the same using a servlet of a filter. The general way is :
in the servlet that processes login you
create a new session
Session old = request.getSession(false); // first invalidate old if it exists
if (old != null) {
session.invalidate();
}
Session session = request.getSession(true); // next create one
put the user id as attribute of the session
session.setAttribute("USERID", userId);
then in the element (filter of servlet) where you want to know whether you have a registered user :
Session = request.getSession(false);
if ((session == null) or (session.getAttribute("USERID") == null)) {
response.sendRedirect(homeUrl);
return; // no need to process further (if in a filter no need to go down the chain)
}
in the servlet after controlling you have a logged on user, forward to the jsp
request.getRequestDispacher("/path/to/displayer.jsp").forward(request, response);
That's all ...
If you want to check this before creating, then do so:
HttpSession session = request.getSession(false);
if (session == null) {
// Not created .
session = request.getSession();
} else {
// Already created.
}
If you don't care about checking this after creating, then you can also do so:
HttpSession session = request.getSession();
if (session.isNew()) {
// newly created.
} else {
// Already created.
}
<% if(session.getAttribute("sessionname")==null)
{
response.sendRedirect("index.jsp");
else
{
String activeUser=session.getAttribute("sessionname").toString();
}
I hope it helps you
Related
Background: I need to create a filter which aims to capture the http response of a servlet whenever it is hit for the first time. Post that on subsequent servlet hit, I need to send the same http response back which i captured earlier. For this, i am saving the servlet response in a text file and send the same as part of response whenever servlet is accessed from second time.
Now, in my application, every screen is painted by 2 servlets. First servlet(for which i am saving http response) sends back basic template along with some dynamic xml data along with xsl name. During load of DHTML response of first servlet, 2nd servlet is called to fetch XSL. As part of security, during first servlet hit, xsl name is added as part of session attribute which is verified when second servlet is called to fetch xsl.
Now, The issue is when i capture http response of first servlet in the filter and re-send the same as part of subsequent hit, session attributes are coming as null in second servlet. (Ques 1: Why?)
Now, to think of the work around, i am adding the session attributes in a concurrenthashmap when I save the http response in the text file. And when the servlet is hit second time, i set the session attributes explicitly and send the response from text file. Now, again, during second servlet hit, these attributes are coming as null. To inspect more, i tried printing the concurrenthashmap in dofilter method. What i observed is that the value of the session attributes are getting null on subsequent servlet hit. (Ques 2: Why?)
public class ServletResponseMocker implements Filter {
private ServletContext context;
private ConcurrentHashMap<String,String> hmURI_FileNameMap=new ConcurrentHashMap<String, String>();
private ConcurrentHashMap<String,List<String>> hmURI_SessionAttrLMap=new ConcurrentHashMap<String, List<String>>();
private String rootPath;
public void init(FilterConfig fConfig) throws ServletException {
this.context = fConfig.getServletContext();
rootPath=System.getProperty("WAR_ROOT_PATH");
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String uri = req.getRequestURI();
boolean bToBeProcessed = false;
if (uri.startsWith("some/pattern"))
bToBeProcessed = true;
if (bToBeProcessed) {
res.setCharacterEncoding(System.getProperty("CHARSETTYPE"));
OutputStream out = res.getOutputStream();
byte responseContent[] = null;
String filename = null;
if (hmURI_FileNameMap.containsKey(uri)) {
filename = hmURI_FileNameMap.get(uri);
responseContent = Utils.readBytesFromFile(rootPath + "\\somefolder\\"
+ filename);
res.setContentType("text/html;charset=UTF-8");
res.setContentLength(responseContent.length);
HttpSession session = req.getSession(false);
if (session != null) {
if (hmURI_SessionAttrLMap.get(uri) != null)
session.setAttribute("ClientXSL",
hmURI_SessionAttrLMap.get(uri));
}
res.setHeader("X-FRAME-OPTIONS", "SAMEORIGIN");
} else {
filename = uri.substring(uri.lastIndexOf("/") + 1) + ".vdb";
hmURI_FileNameMap.put(uri, filename);
ResponseWrapper wrapper = new ResponseWrapper(res);
chain.doFilter(request, wrapper);
HttpSession session = req.getSession(false);
// This session attribute is set by some filter in chain and is
// always not null here.
List<String> clientXSLList = (List) session
.getAttribute("ClientXSL");
if (clientXSLList != null) {
hmURI_SessionAttrLMap.put(uri, clientXSLList);
}
responseContent = wrapper.getData();
/*Writing data to text file*/
}
out.write(responseContent);
out.flush();
out.close();
} else {
// To identify the 2nd servlet of the screen which is same for all
// screens
if(uri.startsWith("/someother/pattern/com.second.servlet.fetchXSL")){
HttpSession session = req.getSession(false);
if (session != null) {
// Below session attributes always comes as not null during
// fisrst time screen loading. However, comes as null when
// static response is sent for subsequent servlet hit.
List<String> clientXSLList = (List) session
.getAttribute("ClientXSL");
if (clientXSLList != null)
this.context.log("Getting clientXSL list from session:"
+ Arrays.toString(clientXSLList.toArray()));
}
}
chain.doFilter(request, response);
}
public void destroy() {
}
}
Ok Found the issue.
For Ques 1: I overlooked the code present in second servlet. It clears the session attributes whenever it is hit. Therefore when i capture the http response of first servlet being hit second time, session attributes already got null. And hence, they were coming as null in second servlet.
For ques 2: Issue was with my code in filter.
List<String> clientXSLList = (List) session
.getAttribute("ClientXSL");
if (clientXSLList != null) {
hmURI_SessionAttrLMap.put(uri, clientXSLList);
}
The session attributes were added in a list which was added as part of session. And then when i was copying the session attribute, i was not cloning it. Hence, the same getting cleared. To resolve this, now i am creating the clone and then adding it to my concurrenthashmap as below.
ArrayList<String> clientXSLList = (ArrayList<String>) session
.getAttribute("ClientXSL");
if (clientXSLList != null) {
hmURI_SessionAttrLMap.put(uri, clientXSLList.clone());
}
I am very new to java servlet programming. I have been writing a simple program for practicing java session. There are two .jsp file. first one called index.jsp, and another one is selection.jsp. And there is a servlet called controller. At first the index.jsp will be called, and user will be submit a input. That will be redirect in servlet controller. In that servlet will check whether it is new request or not. If new then it redirect to other page, else will do some other work.
I am checking whether it is new request or not by session.isNew() method. But it always says it is not new session. But, if I disable the browser cookies option then it is working fine. Now what is my observation is that when in the first I request the index.jsp to the container it assign a session along with that request. So when it comes to servlet it treat as a old session. I got this idea from Head first book Servlet and JSP.
Here is my servlet code -
public class Controller extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String user;
HttpSession session = request.getSession(false);
if (session == null) {
user = request.getParameter("user");
if (user == null) {
response.sendRedirect("index.jsp");
}
session.setAttribute("username", user);
SelectItem selectItem = new SelectItem();
selectItem.setUser(user);
response.sendRedirect("selection.jsp");
session.setAttribute("selectItem", selectItem);
} else {
String selectionItem = request.getParameter("selection");
SelectItem selectItem = (SelectItem) session.getAttribute("selectItem");
if (selectItem != null) {
selectItem.add(selectionItem);
session.setAttribute("selectItem", selectItem);
}
response.sendRedirect("selection.jsp");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
So, how to determine whether it is a new session or old one? Thank you.
HttpSession.isNew API:
Returns true if the client does not yet know about the session or if the client chooses not to join the session. For example, if the server used only cookie-based sessions, and the client had disabled the use of cookies, then a session would be new on each request.
So, you're getting true because the client has cookies disabled. The "new session" check in done in the else block of this check:
HttpSession session = request.getSession(false);
if (session == null) {
// create new session
session = request.getSession();
} else {
// existing session so don't create
}
In your code, you don't appear to be creating a new session when a new session is detected. Perhaps that's where you're stumbling.
Note: learning the basic Servlet API is a good thing. However, for my professional work I use frameworks which simplify my programming, like Spring Boot and Spring Security.
I'm trying so send a User object using HttpSession in login and retrieve data from jsps and some servlets.
Here is how I save object to session in login servlet.
HttpSession session = request.getSession();
User user = new User(1, 001);
user.setType(1);
session.setAttribute("user", user);
response.sendRedirect("index.jsp");
In index.jsp I do some dropdown name list loading.And when dropdown is clcked I go to this servlet. (That dropdown selection process is working perfect. This problem is occured after I use objects with session. Other time I only set values to session not entire object and never faced this problem.)
And here is how I retrieve them in servlet
HttpSession session = request.getSession(false);
if (session != null) {
User user = (User) session.getAttribute("user");
if (user != null) {
int userid = user.getId();
int usertype = user.getType();
} else {
System.out.println("NOOOOOO");
}
}
likewise I call this User object in several servlets. But sometimes when I refresh the page this user object is get empty. I don't know how to fix this. Is something wrong with my data retrieving method.
Thank you.
I am new in jsp. I am trying to do redirection to login page when expire the session.
My code:
String sessionUser = null;
sessionUser = session.getAttribute("UserName").toString();
if(sessionUser == "" || sessionUser == null)
{
System.out.println("In login");
response.sendRedirect("login.jsp");
}
else
{
System.out.println("out login");
}
in above code i get error in line of
sessionUser = session.getAttribute("UserName").toString();
Error
HTTP Status 500 - An exception occurred processing JSP page
How can i do this?
From the error message and your description it seems you have written this code in JSP :
sessionUser = session.getAttribute("UserName").toString();
The above line can throw error if session is null or session doesn't have a UserName attribute .It is bad practice to write scriptlets in JSP.
You need to use a Filter to do anything closer to what you intend to do :
// Do not create session if it doesn't exist
HttpSession session = request.getSession(false);
// check if session is null
if(session != null) {
chain.doFilter(request, response);
} else {
// redirect to login page
response.sendRedirect("/login.jsp");
}
You can implement HttpSessionListener to listen to the session invalidation event. But a Listener is not a good choice here , because it is not tied to a request.
Suppose a person is logged in with user id and password in an app. Now with same user id and password he is trying to log without logging out from first session. I want to make it that it willlog out from and first session and continue with new one automatically.
Struts2, JSP , Java are technologies , i m using for my apps.
Problems facing
IE 8 giving same session id in same machine if we open in new tab or window. Not able to differentiate between different login from same machine.
How to set own session id?
Banking application like SBI sites and all works like that only , how does it work real time?
I want to replicate same thing like SBI bank sites work on online transaction. Send message session out in first window if you open again in new window
Please let me know how does this logging part in details.
Thanks.
This is my filter
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("FirstFilter : In filter doFilter before doFilter...");
HttpServletRequest req = (HttpServletRequest) request ;
HttpServletResponse res = (HttpServletResponse) response ;
HttpSession session = req.getSession(false);
String userId=req.getParameter("username");
String password=req.getParameter("password");
System.out.println(" : : " + req.getParameter("username")) ;
System.out.println(" : " + req.getServletPath());
LoggedInUserVO userProfVOSession = null ;
if(session != null) {
String sessionId=session.getId();
userProfVOSession = (LoggedInUserVO)session.getAttribute("LoggedInUser") ;
//check for login id password and session for single user sign in
if(null!=userProfVOSession){
if(userProfVOSession.getUserName().equalsIgnoreCase(userId) && userProfVOSession.getUserPassword().equals(password) && userProfVOSession.getSessionId().equals(sessionId)){
//do nothing
}
else{
System.out.println("in duplicate");
}
}
}
if(userProfVOSession == null) {
if("/populatelogin.action".equals(req.getServletPath()) || "/login.action".equals(req.getServletPath())||"/images/Twalk-Logo-4-green.png".equals (req.getServletPath())||"css/twalk.css".equals( req.getServletPath() )) {
chain.doFilter(req, res) ;
} else {
req.getRequestDispatcher("Entryindex.jsp").forward(req, res) ;
}
} else {
chain.doFilter(req, res) ;
}
Basically your requirement leads to web security vulnerability.If a person is already logged in, then his session must be active.Now the scenario is like this:
If you tries to login again with the same credentials, he wll be automatically logged in.
If you want to kill the old session for every login, then what you need to do is , you need to get a new session every time when you login, so your old session will be expired.You can achieve this by just writing a filter.In this filter check whether the user is already associated with a session or not, if yes, then invalidate his current session and start new one.This will solve the issue of multiple login attempts.
Remember that when a session is initiated, then the server is sending a cookie back to the user.Henceforth for every subsequent request made, this cookie will be transmitted to the server. Even if that if you open multiple tabs in browsers, this same cookie only is sent back to the server.
Hope I understood this.