Session created by Tomcat - java

I am learning session with servlets and i read in the book that to create a session we need to call as below.
HttpSession session = request.getSession()
This causes the web container to create a session ID and send it back to client so that client can attach it with every subsequent request to the server. When i open developer tools in chrome under request headers in network tab i do see a cookie header.
Cookie: JSESSIONID=F92
Below is what i did in my login servlet
package shop;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
public class LoginServlet extends HttpServlet{
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String uid = request.getParameter("uid");
String password = request.getParameter("pwd");
if(uid.equals("admin") && password.equals("admin"))
{
HttpSession session = request.getSession();
System.out.println(session.getId());
response.sendRedirect("shopping");
}
else
response.getWriter().println("Invalid Credentials");
}
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
this.doGet(request, response);
}
}
Index.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>shopping application</title>
</head>
<body style="background-color:cyan">
<div style="text-align:center">
<h3>Welcome to Mart</h3>
<form action="login" method="post" name="loginform">
<div style="padding:2px;">
<label for="uid">Username:</label>
<input type="text" id="uid" name="uid">
</div>
<div style="padding:2px;">
<label for="pwd">Password:</label>
<input type="password" name="pwd" id="pwd">
</div>
<input type="submit" value="Login">
</form>
</div>
</body>
</html>
My question is that even if i remove the getSession() call i still see the cookie in the network tab. Is there a default session associated with every request by tomcat?

On Tomcat sessions are established lazily, when they are needed. There are basically a couple of situations where sessions are created:
if you call request.getSession() or request.getSession(true) a session is always established,
if you authenticate users against Tomcat's user database a session might be created depending on the authentication method. Most notably if you use form authentication (see this tutorial) a session is always established,
JSP pages create sessions unless you add the <%page session="false"%> directive (see Why set a JSP page session = "false" directive?).
Browsers remember cookies, so the presence of a JSESSIONID is not an indication of the presence of a session (it might be there from a previous test). To test for a presence of a session use request.getSession(false). For example:
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final boolean establishSession = req.getParameter("withSession") != null;
try (final PrintWriter writer = resp.getWriter()) {
final String requestedSessionId = req.getRequestedSessionId();
final HttpSession possibleSession = req.getSession(establishSession);
writer.append("I requested a session with id: ")//
.append(requestedSessionId)
.append("\nI have a session with id: ")
.append(possibleSession != null ? possibleSession.getId() : null)
.println();
}
}
Edit: I added the case of a JSP page creating sessions.

Related

How to configure the return in AMP-Access?

In theory when the AMPByExample server receives the POST request
from the login page, if the credentials are correct, it will redirects
the request to the URL of returnURL and the parameter is added
success = true. Once done, the AMP execution time can finally
authorize the page.
The login page is the following:
login.jsp
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login Page</title>
</head>
<body>
<form method="post" action="loginauthorization">
Correo Electronico: <input type="text" name="correo"><br>
ContraseƱa: <input type="password" name="clave"><br>
<input name="returnurl" type="hidden" value="https://cdn.ampproject.org/v0/amp-login-done-0.1.html?url=https%3A%2F%2Fampbyexample.com%2Fplayground%2F">
<input type="submit" value="Ingresar">
</form>
</body>
</html>
As you can see, in the returnurl it is the same login URL ofAmpByExample and it does not work.
I already tried to make my own url in the following way:
<input name="returnurl" type="hidden" value="https://cdn.ampproject.org/v0/amp-login-done-0.1.html?url=http%3A%2F%2Flocalhost%3A8084%2Fmypage%2Fpanel.jsp">
And it doesn't work either.
In the servlet loginauthorization.java I receive thatreturnurl and I add the # success = true (supposedly I must verify username and password, but I want to make it work first).
loginauthorization.java:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class loginauthorization extends HttpServlet {
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
response.setContentType("text/html");
//I get the parameters
String email = request.getParameter("correo");
String password = request.getParameter("clave");
String url = request.getParameter("pageurl");
int ridini = url.indexOf("rid=")+4;
int ridend = url.indexOf("&url=");
String rid = url.substring(ridini, ridend);
String returnurl = request.getParameter("returnurl");
//assuming that the username and password are correct, add to the returnurl success true
returnurl= returnurl + "#success=true";
//create a session
HttpSession session=request.getSession();
session.setAttribute("umail",email);
session.setAttribute("upass",password);
session.setAttribute("rid",rid);
session.setAttribute("returnurl",returnurl);
//redirect after login with the success = true
response.sendRedirect(returnurl);
}catch(Exception exp){
System.out.println(exp);
}
}
}
The configuration of the panel is as follows:
panel.jsp
<script id="amp-access" type="application/json">
{
"authorization": "http://localhost:8084/mypage/jsonauthorization",
"noPingback": "true",
"login": {
"sign-in": "/mypage/login.jsp?rid=READER_ID&url=CANONICAL_URL&return=RETURN_URL",
"sign-out": "/mypage/endsession"
},
"authorizationFallbackResponse": {
"loggedIn": false
},
"type": "server"
}
</script>
The jsonauthorization prints{"loggedIn": true}or{"loggedIn": false}:
jsonauthorization.java
import java.io.*;
import javax.servlet.http.*;
public class jsonauthorization extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response){
try{
response.setContentType("application/json");
response.setHeader("AMP-Access-Control-Allow-Source-Origin", "http://localhost:8084/mypage");
PrintWriter pwriter = response.getWriter();
HttpSession session=request.getSession(false);
if(session != null){
String email=(String)session.getAttribute("umail");
if(email==null){
session.invalidate();
pwriter.print("{\"loggedIn\":false}");
}else{
String rid;
rid = (String) session.getAttribute("rid");
Cookie AmpCookie = new Cookie("authorized",rid);
AmpCookie.setPath("/");
AmpCookie.setDomain("/mypage");
response.addCookie(AmpCookie);
pwriter.print("{\"loggedIn\":true}");
}
}else{
pwriter.print("{\"loggedIn\":false}");
}
pwriter.close();
}catch(Exception exp){
System.out.println(exp);
}
}
}
I appreciate the answers, if the error is not in the returnurl please tell me where :P
I am also trying to figure out AMP integration with login/registration. Not sure if this will help, but I found that the return url is automatically added to the url param, so you don't necessarily have to add it to your sign-in url within your initialization json object.
I figured out, it is not necessary to configure the return url. Simply add the hidden input inside the html in order to close the login window and read the json url approving the login.
Just like this:
<input name = "returnurl" type = "hidden" value = "https://cdn.ampproject.org/v0/amp-login-done-0.1.html">
Then, if the json url aproves the login it will works.
Actually the code is fine, the problem was in the json generator file.
CORS problems. Is necessary to set the header "AMP-Access-Control-Allow-Source-Origin" right.

Multiple servlet communication

I have a simple servlet 'Login' deployed in Server A tomcat
Index.jsp
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Login</h1>
<form method="post" action="Validate">
User: <input type="text" name="user" /><br/>
Password: <input type="text" name="pass" ><br/>
<input type="submit" value="submit">
</form>
</body>
Validate.java
doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("text/html;charset=UTF-8");
String name = request.getParameter("user");
String pass = request.getParameter("pass");
if(pass.equals("1234"))
{
//creating a session
HttpSession session = request.getSession();
session.setAttribute("user", name);
response.sendRedirect("Welcome");
}
else
{
PrintWriter out = response.getWriter();
out.println("Wrong password!!!");
}
}
Welcome.Java
doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
String user = (String)session.getAttribute("user");
out.println("Welcome"+user);
}
This set up works fine.
Now what I want to try is to create another Servlet 'Validate' which would be deployed in another Server B tomcat with a different IP. I need to pass the parameters from Servlet 'Login' to Servlet 'Validate' which will then validate the credentials and send back the validation message, a String, to the Servlet 'Login' which will then display the same on its index.jsp page.
Please provide some help on this. Let me also add that I have no prior experience in servlets.

Is it better to invalidate a session in a servlet in which it is declared or in the jsp page where its values will be used?

Is it better to invalidate a session in a servlet in which it is declared or in the JSP page where its values will be used ?
I am posting the code of servlet below -
package Controller.UploadInfo;
import File.FileOperations;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import Controller.DatabaseException.*;
public class AttendenceInfoUpload extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
HttpSession session;
if (FileOperations.fileUpload(request)) {
try {
FileOperations.excelToAttendence();
request.getRequestDispatcher("UploadSuccess.jsp").forward(request, response);
} catch (DBException e) {
session = request.getSession(true);
session.setAttribute("exception",e);
request.getRequestDispatcher("FileUpload.jsp").forward(request, response);
session.invalidate();
}
} else {
session = request.getSession(true);
session.setAttribute("exception"," File Upload Failed " );
request.getRequestDispatcher("FileUpload.jsp").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);
}
#Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
In the given servlet above I have invalidated the session right after the getRequestDispatcher() in the catch block. Although the code is working, my concern is will it cause the exception message to loose before it can be displayed in the JSP page. Or is it better to invalidate the session declared in the servlet in the JSP page where its values will be displayed.
The JSP page -
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#page import = "java.io.*" %>
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>Excel File Upload Example</h1>
<form name="form1" method="post" action="AttendenceInfoUpload" enctype="multipart/form-data">
<table border="1">
<col width="120">
<tr>
<td>Upload Excel File:</td>
<td><input type="file" name="Select File"/></td>
</tr>
<tr>
<td> </td>
<td><input name="" type="submit" value="upload" /></td>
</tr>
</table>
</form>
<c:if test="${not empty exception}">
<label>
<font color="red">
<c:out value="Error:${exception}"></c:out>
</font>
</label>
</c:if>
</body>
</html>
One can suggest an alternate solution as well?
The best solution is probably to invalidate the session in the servlet but make sure that any values required by the JSP are stored in the request rather than in the session. I say this because it is best practice to put all logic in beans or servlet code and keep JSPs for layout only.
There's no need to invalidate a session. Also there's no need to use a session attribute. If you want to forward to a error page you can use request attribute. Using a session heavily is a bad practice because it requires a lot of memory to utilize those variables you put into it.
} catch (DBException e) {
request.setAttribute("exception",e);
request.getRequestDispatcher("FileUpload.jsp").forward(request, response);
}
as I said it's not a good practice to invalidate a session when you are going to forward to a error page. Even if JSP page is rendered in the same thread other threads that can use the same session might not work. And you can't use session variables after the session is invalidated. However it's rarely happens but other request might invalidate a session while JSP is rendered.

How do I invalidate a login session initialized in one servlet in another servlet with a href in between?

I am working on a web app and I have to implement a login/logout system. I have already implemented the login system(validating by verification through a database) in a controller servlet. Basically the most important aspect of my project is to keep a MVC approach.So here is the controller login servlet that I have implemented,
package com.cid_org.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.cid_org.model.*;
import java.sql.*;
/**
* Servlet implementation class LoginControllerServlet
*/
public class LoginControllerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public LoginControllerServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*Take the data submitted by the user though the login
* form(Remember the HTTP Post request ->HttpServletRequest request object*/
String username = request.getParameter("username");
String pwd = request.getParameter("pass");
System.out.println(username + "aaa");
System.out.println(pwd);
Connection connection = (Connection)getServletContext().getAttribute("connection_context_param");
LoginModelPOJO lmpojo = new LoginModelPOJO(username, pwd, connection);
boolean isUserValidFlag = lmpojo.isValid();
if(isUserValidFlag){
/*Entering this block indicates the user has been validated and if the
* user has been validated, we should start a session. But here is a
* question, where exactly(at which point) should we say that user has
* logged in? -I guess when the user sends his/her our login info.
* for validation and right at the moment the info. gets validated,
* we can say at this particular point in program he is IN. And this
* is the precise point for a Login session to start. So remember
* at this point we are logged in*/
/*Getting the session*/
HttpSession session = request.getSession();
RequestDispatcher view =request.getRequestDispatcher("/view/view_profile.jsp");
view.forward(request, response);
}
else{
/*And obviously the unauthorized user will be redirected to the login page.*/
response.sendRedirect("login.html");
}
}
}
And here is the view_profile.jsp,I dispatch the request to,
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Crime Investigation Department-User" content="text/html; charset=ISO-8859-1">
<title>Criminal Investigation Department</title>
<link rel="stylesheet" href="/CrimeReportingSystem5/static/css/view_profile_page.css">
</head>
<body>
<img src="css/images/logo/CID_Logo_1.png" alt="CID Logo">
<nav id="navigation">
<a id="link1" class="header_links" href="most_wanted.html">Most Wanted</a>
<a id="link2" class="header_links" href="hotnews.html">Hot News</a>
<a id="link3" class="header_links" href="report_crime.html">Report Crime</a>
<a id="link4" class="header_links" href="login.html">Login</a>
<a id="link5" class="header_links" href="about.html">About Us</a>
<a id="link6" class="header_links" href="contact.html">Contact Us</a>
<a id="link7" class="header_links" href="safety_measures.html">Safety Measures</a>
</nav>
<%
/*Remember we got to this page only after validation of the username
*from the servlet ,point being the username has already been validated
*so all we got to do here is retrieve the username form the request
*object and it.*/
String username = request.getParameter("username");
if(username == null){
response.sendRedirect("/CrimeReportingSystem5/static/login.html");
}
%>
<div id="login_page_border">
<span id="welcome_username_text">Welcome <%=username%></span>
View Complaints
Edit Profile
Logout
<div id="profile_layout">
</div>
</div>
</body>
</html>
My problem: I want to implement a logout system for which I already generated a session in Login servlet and I have decided to invalidate the session in another Logout servlet but there lies a link in between them(see the jsp) so the request sent will be a GET request to the servlet,how can I send session info. to the Logout servlet for the invalidation.Btw, I have read another answer in which it was suggested to create a static Map variable and store JSESSIONID and session as map variable but even if I did that,how would I know which user clicked the logout link?
Note: I can't use JavaScript or Jquery for the solution cause I am yet to read them. Please provide a simple solution.
You see problems where no problems are.
It's quite easy to invalidate the current session inside a servlet:
// Check, if there is a session active. Avoid to create a new one.
HttpSession session = request.getSession(false);
if(session != null) {
session.invalidate();
}
It doesn't matter, if this code runs in a different servlet than where you created the session.
Internally the session is usually managed by a browser cookie. So when you create a new session the server sends a cookie to the browser associated to the domain. Then each subsequent request the browser transmits this cookie to your server. Your servlet server implementation (like Tomcat) then checks this cookie against the active sessions, so that your next request.getSession() returns the right session corresponding to the specific user.

JSP Form Not Connecting with Servlet 404-Error

I'm having a little issue connecting with my servlet so that I can pass some data to a mysql database. I've read a bunch of the threads here, but have had no luck with suggestions to other members.
I have a jsp page named "insertData.jsp" On that page there is a form where the action points to a servlet named "UpdateData". When I click submit on the web page, I get a 404 error stating that the requested resource is not available. I have also updated my web xml file to try to point to the right direction.
So here's my folder setup:
The UpdateData.java is in the controller package of the source packages folder. The name of the project is "RukertContainerTracker".
Here's my jsp page:
<%#taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%>
<%#page import="java.sql.ResultSet"%>
<%#page import="java.sql.Statement"%>
<%#page import="java.sql.DriverManager"%>
<%#page import="java.sql.Connection"%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert Data</title>
</head>
<body>
<h1>Insert Data Into Container Records</h1>
<H1>The Rukert Terminals Container Tracker </H1>
<form name="Insert Record" action="/UpdateData" method="Post">
Container Number: <input type="text" name="containerNumber"> <br />
Full Out: <input type="date" name="fullOut" /> <br/>
Empty In: <input type="date" name="emptyIn" /> <br/>
Empty Out <input type="date" name="emptyOut" /> <br/>
Full In: <input type="date" name="fullIn" /> <br/>
Comments: <input type="text" name="comments" /> <br/>
<input type="submit" value="Submit" />
</form>
<div>
<a href="javascript:history.back();">
<span class="categoryLabelText">HOME</span>
</a>
</div>
</body>
</html>
My servlet:
package controller;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UpdateData extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, SQLException {
//Get container data from the JSP page
String container=request.getParameter("containerNumber");
String fullOutDate=request.getParameter("fullOut");
String emptyInDate=request.getParameter("emptyIn");
String emptyOutDate=request.getParameter("emptyOut");
String fullInDate=request.getParameter("fullIn");
String comments=request.getParameter("comments");
//Print the above got values in console
System.out.println("The username is" +container);
System.out.println("\nand the password is" +fullOutDate);
String connectionparams="jdbc:mysql://localhost:3306/rukerttracker";
String db="rukerttracker";
String uname="root";
String psword="Colorado1982";
Connection connection=null;
ResultSet rs;
try {
// Loading the available driver for a Database communication
Class.forName("com.mysql.jdbc.Driver");
//Creating a connection to the required database
connection = DriverManager.getConnection
(connectionparams, uname, psword);
//Add the data into the database
String sql = "insert into containerinventory values (?,?,?,?,?,?)";
try (PreparedStatement prep = connection.prepareStatement(sql)) {
prep.setString(1, container);
prep.setString(2, fullOutDate);
prep.setString(3, emptyInDate);
prep.setString(4, emptyOutDate);
prep.setString(5, fullInDate);
prep.setString(6, comments);
prep.executeUpdate();
}
}catch(Exception E){
System.out.println("The error is=="+E.getMessage());
}
finally{
connection.close();
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userPath = request.getServletPath();
// if category page is requested
if (userPath.equals("/insertData")) {
// TODO: Implement category request
// use RequestDispatcher to forward request internally
String url = "/WEB-INF/view" + userPath + ".jsp";
try {
request.getRequestDispatcher(url).forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
And finally my web.xml page:
<servlet>
<servlet-name>ControllerServlet</servlet-name>
<servlet-class>controller.ControllerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ControllerServlet</servlet-name>
<url-pattern>/chooseLanguage</url-pattern>
<url-pattern>/viewTracker</url-pattern>
<url-pattern>/editTracker</url-pattern>
<url-pattern>/addToCart</url-pattern>
<url-pattern>/viewCompany</url-pattern>
<url-pattern>/category</url-pattern>
<url-pattern>/updateCart</url-pattern>
<url-pattern>/purchase</url-pattern>
<url-pattern>/viewCart</url-pattern>
<url-pattern>/checkout</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>UpdateData</servlet-name>
<servlet-class>controller.UpdateData</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UpdateData</servlet-name>
<url-pattern>/insertData</url-pattern>
</servlet-mapping>
I have two servlets, I don't know if this matters, but I couldn't get the application to work in the controller servlet, so I created the Update Data servlet.
Any help as to why I keep getting this 404 error would be greatly, greatly appreciated. Thanks for taking the time to look at this.
I think in form you are using POST method and your servlet does not have post method. please check it.
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{...}
not available.

Categories