I have been trying to find the reason as to why my session would be lost when I do a POST.
I am checking my session all throughout my app but the session will drop when I call a particular servlet and it only drops on this particular one. The issue is intermittent so it is very frustrating. I'm not sure what is needed so I'll put as much info as I can up.
The page is accessed through a servlet. I can verify that the session is still the same.
As the user is routing through the app, I can see that the session is still the same.
Checking Session:HTTP Session CEHKIIMEKHMH
Calling Get Details
Checking Session:HTTP Session CEHKIIMEKHMH
Calling Project Details
Checking Session:HTTP Session CEHKIIMEKHMH
Calling Attachment Controller
Checking Session:HTTP Session CEHKIIMEKHMH
public class Attachments extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Calling Attachment Controller");
HttpSession session = request.getSession(false);
System.out.println("Checking Session:"+session);
if(session != null){
Object projectId = session.getAttribute("projectId");
request.getRequestDispatcher(response.encodeURL("views/attachments.jsp")).forward(request, response);
}else{
System.err.println("Invalid session");
response.sendRedirect("/");
}
}
}
Here is my form posting. The form is actually submitted via javascript after I perform validation, I just merely call $('#files).submit(); not sure if that really matters or not.
<form id="files" name="files" method="POST" action="FileUpload" enctype="multipart/form-data">
The moment they post, the session is lost
Calling File Upload
Checking Session:null
null
Here is the start of the servlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Calling File Upload");
HttpSession session = request.getSession(false);
System.out.println("Checking Session:"+session);
if(session != null){
Object projectId = session.getAttribute("projectId");
System.out.println("Accessing File Upload: Session is valid");
It's the same method all across the board. I have no idea what the problem is.
I've narrowed down the issue but I still have not resolved it yet. It happens during my redirect. I also was not encoding the URL correctly. I have modified all my redirects to have the folowing:
request.getRequestDispatcher(response.encodeRedirectURL("views/attachments.jsp")).forward(request, response);
This only resolves it on the server side though and does not provide a solution when I am handling redirects from the client.
Related
Hey there just got some questions i want to validate before i will start implementing login flow on my website.
So basically which way is safer / better / more optimal to do.
Let's get to the point. What I'am trying to achieve is some kind of control panel for administrator, its seperate website which allows to manage very important data.
How i want it work is to make it as secure as possible meanwhile being optimized because data will be displayed live through sockets.
So let's get to the point..
url.com/ is root url, which consists of login panel, I want to hide other page's so no one can access them meanwhile authoriziting users.
Before i start with authorization method i got a question about authentication (not sure if named them right =P)
Which authentication is safer, i send POST with username / password and should i return token which i shall save in sessionStorage and then send token with every request (that's how i did it with my REST API) or should i do it in java with.
//validate with db and if valid.
HttpSession session = request.getSession();
session.setAtrribute("token",token);
So i red a bit and came to this conclusion.
Method no.1 creating a filter for all pages which prevents from accessing them through URL.
#WebFilter("/*")
public class LoginFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("token") == null) {
response.sendRedirect(request.getContextPath() + "/");
} else {
//check if token is not expires or if exists with database
chain.doFilter(req, res); // Logged-in user found, so just continue request.
}
}
}
Method no.2 using servlets to map urls and read them from WEB-INF.
#WebServlet("/dashboard")
public class SearchServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException{
request.getRequestDispatcher("/WEB-INF/dashboard.html").forward(request, response);
}
}
and reading from WEB-INF would be in doPOST method, with token sent in header Authoriization, if valid then redirect to page from WEB-INF else to login.
If my question is somehow dumb im sorry, i'am 2nd year student and still learning.
I ran the code in the debugger and confirmed that the object was being created in the Java code and was null in the JSP. Why is the JSP using a new session?
In debugger, it goes into Java code and sets the captcha in a session with an id. When I run the JSP, it gets the session with a different id, fails, then goes into doGet() and sets the current id session with a new captcha object. Storing captcha in a session, but that session isn't being used when the JSP runs.
Here are some code snippets
Java:
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ColoredEdgesWordRenderer wordRenderer = new ColoredEdgesWordRenderer(COLORS, FONTS);
Captcha captcha = new Captcha.Builder(_width, _height).
addText().addNoise().
addBackground(new BrightGradiatedBackgroundProducer()).
build();
CaptchaServletUtil.writeImage(resp, captcha.getImage());
req.getSession().setAttribute("simpleCaptcha", captcha); // object is getting set
}
JSP:
session=request.getSession(false);
if (session==null)
session=request.getSession(true);
boolean isCaptchaTrue = false;
String strCaptcha = request.getParameter("captcha");
String captchaType = request.getParameter("captchaType");
if (strCaptcha != null && captchaType != null) {
if(session.getAttribute("simpleCaptcha") instanceof Captcha){
Captcha captcha = (Captcha) session.getAttribute("simpleCaptcha");
isCaptchaTrue = captcha.isCorrect(strCaptcha);
}else if(session.getAttribute("simpleCaptcha") instanceof AudioCaptcha){
AudioCaptcha captcha = (AudioCaptcha) session.getAttribute("simpleCaptcha");
isCaptchaTrue = captcha.isCorrect(strCaptcha);
}
}
I found my problem. At the top of the JSP the session was being invalidated. I removed session.invalidate() and it works now.
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 have an authorization frame displayed on every page and I want to keep that page displaying even if the user will choose to log in (using jstl tags i will simply put instead of this frame user info and link to shopping cart). How can i achieve that ? I have some ideas, but they all breaking out my controller design.
public class FrontController extends HttpServlet {
private ActionContainer actionContainer = ActionContainer.getInstance();
public FrontController() {
super();
}
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* #param request servlet request
* #param response servlet response
* #throws ServletException if a servlet-specific error occurs
* #throws IOException if an I/O error occurs
*/
#SuppressWarnings("unchecked")
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String page = null;
try {
Action action = actionContainer.getAction(request);
page = action.execute(request, response);
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(page);
dispatcher.forward(request, response);
} catch (ActionNotFoundException e) {
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(PageNames.ERR_PAGE);
request.setAttribute(AttributeNames.ERR_MESSAGE_ATTRIBUTE, "Unknown Action command: " + e.getMessage());
dispatcher.forward(request, response);
} catch (Exception e) {
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(PageNames.ERR_PAGE);
request.setAttribute(AttributeNames.ERR_MESSAGE_ATTRIBUTE, "Exception:\n" + e.getMessage());
dispatcher.forward(request, response);
}
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
* #return a String containing servlet description
*/
#Override
public String getServletInfo() {
return "Front Controller";
}
#Override
public void init() throws ServletException {
super.init();
Locale.setDefault(new Locale("ru","RU"));
}
}
I was thinking about of redirecting to especially written for this case page, which will redirect to the original page, or to check page string for null and reloading from controller the original page, but i cannot clearly understand how to do this.
Your question isn't clear enough. But I think you're asking how you can replace a certain component on a page (Login button) with an other (username, welcome message and shopping cart details) after the user logs in.
If I understand your requirements, then what I would do after the user logs in is set a cookie (or a value in localStorage). The cookie is added to the Set-Cookie response header by means of the addCookie method of HttpServletResponse. Here's an example:
Cookie userCookie = new Cookie("user", "uid1234");
response.addCookie(userCookie);
Then in your controller simply check if the "user" value is set or not and take the appropriate action. A tutorial on servlets with cookies.
If you need to handle the front-end component, and change values on the form without reloading the page, I would recommend using javascript to do this, you can find and remove the old DOM elements with new ones (User's name, Welcome message, shopping cart, whatever).
If your iFrame is doing the login, then on successful login, have it call a function in your top window that does the update after reading the updated values from the cookie.
If you want to handle this completely at the front-end, i.e. Javascript, then I would skip using cookies and use localStorage instead. There is plenty of help on Stackover and on the internet about what localStorage is, but I will suggest the YUI Storage Lite library which makes storing and loading data from localStorage very simple.
Regards,
Include the current URL as a hidden field of your authentication form. In the action handling the authentication, once the user is authenticated, redirect to this URL.
In the JSPs, test if the user is authenticated and include the authentication form or the shopping cart. This test can be done by just putting a boolean value in the HTTP session once the user is authenticated.
i have a JSP web page that refreshes every 1 minute.
on each refresh, the session object is checked for validity.
When the tomcat web server restarts, the session goes away...and when the page refreshes, it says "invalid". anyone has a solution to my problem?
Have a look at the configuration in your Tomcat config file. The documentation is at http://tomcat.apache.org/tomcat-6.0-doc/config/manager.html Look for the section on persistent managers ...
You have to make sure that ALL your objects your store in your Session are Serializable. If one of them isn't (or doesn't meet the Serializable requirements) you will lose your session on web app reload or tomcat restart.
EG: The following works fine for a Servlet:
public class MainServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
HttpSession session = request.getSession();
Date date = (Date) session.getAttribute("date");
if (date == null) {
date = new Date();
session.setAttribute("date", date);
}
response.setContentType("text/plain");
PrintWriter pw = response.getWriter();
pw.println("New Session? " + session.isNew());
pw.println("Date : " + date);
pw.flush();
}
}