In JSP new session is created by default, if non present, so you will always get non null session. You can disable that by adding following page directive to your page:

 <%@ page session="false" %>

JSPs create a session unless explicitly configured not to.Instead of checking for the existence of a session check for a value in the session.

When session calls invalidate() it removes that session from server context and all associated data with that session.When you make new request it creates new one and so you see null as the data because new session doesn’t have data in it

You should check for a logical attribute inside session to validate it user is logged in or not, instead of session itself

getSession(false) – will return current session if current session will not exist then it will NOT create new session.

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). In addition all session attributes bound to the session are removed. However if your code still has references to the session or any of its attributes then these will still be accessible:

  if(request.getSession() != null)
  {
    System.out.println("Session is Created for Each Request with Unique Session ID");
  }

  HttpSession session = request.getSession();
  session.setAttribute("Name", "Mugil");

  String Name = (String) session.getAttribute("Name");
  System.out.println(session.getId());
  System.out.println(session.getAttribute("Name"));

  session.invalidate();

  if(session == null)
  {
    System.out.println("session is Null");
  }

  if(request.getSession(false) == null)
  {
    System.out.println("request.getSession(false) is Null");
  }

  if(request.getSession() != null)
  {
    System.out.println("request.getSession() is Not Null");
  }

  System.out.println(session.getId());
  System.out.println(Name);    

Output

Session is Created for Each Request with Unique Session ID
7A46A65BCDC436030AA10385998F0272
Mugil
request.getSession(false) is Null
request.getSession() is Not Null
7A46A65BCDC436030AA10385998F0272
Mugil

Note
Session is created for each request. So if you are invalidating a session of login page in the next page you should check for existence of userName as session attribute instead of checking session is null because session can never be null

The problem is that the requested page is been loaded from the browser cache instead of straight from the server. You just need to instruct the browser to not cache all the restricted JSP. This way the browser is forced to request the page from the server instead of from the cache and hence all login checks on the server will be executed.

You can do this using a Filter which sets the necessary response headers in the doFilter() method:

@WebFilter
public class NoCacheFilter implements Filter 
{
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
   {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");       
        response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
        response.setDateHeader("Expires", 0); // Proxies.
        chain.doFilter(req, res);
    }
    // ...
}

Map this Filter on an url-pattern of interest, for example *.jsp.

@WebFilter("*.jsp")

Or if you want to put this restriction on secured pages only, then you should specify an URL pattern which covers all those secured pages. For example, when they are all in the folder /app, then you need to specify the URL pattern of /app/*.

 @WebFilter("/app/*")

Even more, you can do this job in the same Filter as where you’re checking the presence of the logged-in user.

Complete Authentication Filter
The filter (the interceptor) shouldn’t check the validity of the username/password combo. That’s the responsibility of the servlet (the controller).

The filter should merely check if the user is logged-in or not (usually by just checking the presence of a session attribute) and then continue the request or block it by redirecting back to the login page.

@WebFilter("/*")
public class LoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        String loginURI = request.getContextPath() + "/login";

        boolean loggedIn = session != null && session.getAttribute("user") != null;
        boolean loginRequest = request.getRequestURI().equals(loginURI);

        if (loggedIn || loginRequest) {
            chain.doFilter(request, response);
        } else {
            response.sendRedirect(loginURI);
        }
    }

    // ...
}

The servlet should collect the submitted data, find the associated User in database and if found then store it as a session attribute and then redirect to the home page, else redisplay the form with validation errors.

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @EJB
    private UserService userService;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        Map<String, String> messages = new HashMap<String, String>();

        if (username == null || username.isEmpty()) {
            messages.put("username", "Please enter username");
        }

        if (password == null || password.isEmpty()) {
            messages.put("password", "Please enter password");
        }

        if (messages.isEmpty()) {
            User user = userService.find(username, password);

            if (user != null) {
                request.getSession().setAttribute("user", user);
                response.sendRedirect(request.getContextPath() + "/home");
                return;
            } else {
                messages.put("login", "Unknown login, please try again");
            }  
        }

        request.setAttribute("messages", messages);
        request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
    }
}

A common misunderstanding among starters is that they think that the call of a forward(), sendRedirect(), or sendError() would magically exit and “jump” out of the method block, hereby ignoring the remnant of the code. For example:

protected void doPost() {
    if (someCondition) {
        sendRedirect();
    }
    forward(); // This is STILL invoked when someCondition is true!
}

This is thus actually not true. They do certainly not behave differently than any other Java methods (expect of System#exit() of course). When the someCondition in above example is true and you’re thus calling forward() after sendRedirect() or sendError() on the same request/response, then the chance is big that you will get the exception:

java.lang.IllegalStateException: Cannot forward after response has been committed

If the if statement calls a forward() and you’re afterwards calling sendRedirect() or sendError(), then below exception will be thrown:

java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed

To fix this, you need either to add a return; statement afterwards

protected void doPost() 
{
    if (someCondition) 
    {
        sendRedirect();
        return;
    }
    forward();
}

… or to introduce an else block.

protected void doPost() {
    if (someCondition) {
        sendRedirect();
    } else {
        forward();
    }
}

Another probable cause is that the servlet writes to the response while a forward() will be called, or has been called in the very same method.

protected void doPost() 
{
    out.write("some string");
    // ... 
    forward(); // Fail!
}

The response buffer size defaults in most server to 2KB, so if you write more than 2KB to it, then it will be committed and forward() will fail the same way:

java.lang.IllegalStateException: Cannot forward after response has been committed

Solution is obvious, just don’t write to the response in the servlet. That’s the responsibility of the JSP. You just set a request attribute like so request.setAttribute(“data”, “some string”) and then print it in JSP like so ${data}

The best way to resolve this problem just set the page (where you suppose to forward the request) dynamically according your logic. That is:

protected void doPost(request , response){
String returnPage="default.jsp";
if(condition1){
 returnPage="page1.jsp";
}
if(condition2){
   returnPage="page2.jsp";
}
request.getRequestDispatcher(returnPage).forward(request,response); //at last line
}

What is Event
Changing the state of an object is known as an event.We can perform some important tasks at the occurrence of these exceptions, such as counting total and current logged-in users, creating tables of the database at time of deploying the project, creating database connection object etc.

Event Types

  1. ServletRequestEvent – ServletRequestListener
  2. ServletContextEvent – ServletContextListener
  3. ServletRequestAttributeEvent – ServletRequestAttributeEvent
  4. ServletContextAttributeEvent – ServletContextAttributeListener
  5. HttpSessionEvent – HttpSessionListener
  6. HttpSessionBindingEvent – HttpSessionAttributeListener

Listener Types

What is Filter
A filter is an object that is invoked at the preprocessing and postprocessing of a request.

It is mainly used to perform filtering tasks such as conversion, logging, compression, encryption and decryption, input validation etc.

The servlet filter is pluggable, i.e. its entry is defined in the web.xml file, if we remove the entry of filter from the web.xml file, filter will be removed automatically and we don’t need to change the servlet.

Filter interface
Filter interface contains three methods

  1. public void init(FilterConfig config)init() method is invoked only once. It is used to initialize the filter.
  2. public void doFilter(HttpServletRequest request,HttpServletResponse response, FilterChain chain)doFilter() method is invoked every time when user request to any resource, to which the filter is mapped.It is used to perform filtering tasks.
  3. public void destroy()This is invoked only once when filter is taken out of the service.

How to define a Filter
web.xml

<web-app>        
	<filter>  
		<filter-name>...</filter-name>  
		<filter-class>...</filter-class>  
	</filter>         
	<filter-mapping>  
		<filter-name>...</filter-name>  
		<url-pattern>...</url-pattern>  
	</filter-mapping>        
</web-app>  

Example of Filter
web.xml


<web-app>
        <servlet>
		<servlet-name>AdminServlet</servlet-name>
		<servlet-class>AdminServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>AdminServlet</servlet-name>
		<url-pattern>/servlet1</url-pattern>
	</servlet-mapping>

	<filter>
		<filter-name>f1</filter-name>
		<filter-class>MyFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>f1</filter-name>
		<url-pattern>/servlet1</url-pattern>
	</filter-mapping>
</web-app>  

MyFilter.java

public class MyFilter implements Filter 
{
  public void init(FilterConfig arg0) throws ServletException 
  {
  }

  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
	throws IOException, ServletException {
  PrintWriter out = resp.getWriter();
  out.print("filter is invoked before");

  chain.doFilter(req, resp);// sends request to next resource
  out.print("filter is invoked after");
}

  public void destroy() 
  {
  }
}

HelloServlet.java

public class HelloServlet extends HttpServlet 
{
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.print("<br>welcome to servlet<br>");
	}
}

Whenever the /Servlet1is accessed it will go through the filter before and after processing the actual java page HelloServlet.java

How to access Init param in filter
web.xml

.
<filter>
	<filter-name>f1</filter-name>
	<filter-class>MyFilter</filter-class>
	<init-param>
		<param-name>construction</param-name>
		<param-value>no</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>f1</filter-name>
	<url-pattern>/servlet1</url-pattern>
</filter-mapping>  
.
.

MyFilter.java

public class MyFilter implements Filter 
{
	FilterConfig config;

	public void init(FilterConfig config) throws ServletException 
	{
		this.config = config;
	}

	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException {

		PrintWriter out = resp.getWriter();

		String s = config.getInitParameter("construction");

		if (s.equals("yes")) {
			out.print("This page is under construction");
		} else {
			chain.doFilter(req, resp);// sends request to next resource
		}
	}

	public void destroy() {
	}
}

Context path
The context path is the prefix of a URL path that is used to select the context(s) to which an incoming request is passed. Typically a URL in a Java servlet server is of the format http://hostname.com/contextPath/servletPath/pathInfo, where each of the path elements can be zero or more / separated elements.

How to get ContextPath

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException 
{
  ServletContext servletContext = getServletContext();
  String contextPath = servletContext.getRealPath(File.separator);
  PrintWriter out = response.getWriter();
  out.println("<br/>File system context path (in TestServlet): " + contextPath);
}

ServletConfig

  1. ServletConfig is one of the pre-defined interface.
  2. ServletConfig object is used for developing flexible servlets.
  3. ServletConfig objct exist one per servlet program.
  4. An object of ServletConfig created by the container during its initialization phase.
  5. An object of ServletConfig is available to the servlet during its execution, once the servlet execution is completed, automatically ServletConfig interface object will be removed by the container.
  6. An object of ServletConfig interface contains details at web.xml, of a particular servlet.
  7. The moment when we are using an object of ServletConfig, we need to configure the web.xml by writing tag under tag of web.xml.
  8. When ever compiler executes init() mehod then the ServletConfig will be created in general.
  9. An object of ServletConfig contain the data in the form of key,value pairs, here the keys represents init param names and values are its values, which are represented in the web.xml file

How to Get ServletConfig Object into Servelt
Method1

ServletConfig conf = getServletConfig();

Method2
ServletConfig object will be available in init() method of the servlet.

public void init(ServletConfig config)
{
// …………………
}

How to Retrieve Data from ServletConfig Interface Object

public String getInitParameter(“param name”);
public Enumeration getInitParameterNames();

web.xml

<web-app> 
  <servlet>
     <servlet-name>onServletConfig</servlet-name>
     <servlet-class>java4s.OnServletConfig</servlet-class> 
     <init-param>
        <param-name> n1 </param-name>
        <param-value> 100 </param-value>
     </init-param>
    .
    .
</web-app>

Test.java

ServletConfig conf=getServletConfig(); 
String s1=conf.getInitParameter("n1");
 

ServletContext
An object of ServletContext is created by the web container at time of deploying the project. This object can be used to get configuration information from web.xml file. There is only one ServletContext object per web application.

Methods of ServletContext interface

  1. public String getInitParameter(String name):Returns the parameter value for the specified parameter name.
  2. public Enumeration getInitParameterNames():Returns the names of the context’s initialization parameters.
  3. public void setAttribute(String name,Object object):sets the given object in the application scope.
  4. public Object getAttribute(String name):Returns the attribute for the specified name.
  5. public Enumeration getInitParameterNames():Returns the names of the context’s initialization parameters as an Enumeration of String objects.

web.xml

    <web-app>  
     ......  
          
      <context-param>  
        <param-name>parametername</param-name>  
        <param-value>parametervalue</param-value>  
      </context-param>  
     ......  
    </web-app>  

Test.java

  ServletContext context=getServletContext();    

  //Getting the value of the initialization parameter and printing it  
  String driverName=context.getInitParameter("parametername");  

SessionId is used to keep track of request coming from the same client during a time duration.

URL rewriting
URL rewriting is a method of session tracking in which some extra data (session ID) is appended at the end of each URL. This extra data identifies the session. The server can associate this session identifier with the data it has stored about that session. This method is used with browsers that do not support cookies or where the user has disabled the cookies. If you need to track Session from JSP pages, then you can use tag for URL-rewriting. It automatically encodes session identifier in URL.

Cookies
A cookie is a small amount of information sent by a servlet to a Web browser. A cookie is saved by the browser and later sent back to the server in subsequent requests. A cookie has a name, a single value, expiration date and optional attributes. A cookie’s value can uniquely identify a client. Since a client can disable cookies, this is not the most secure and fool-proof way to manage the session. If Cookies are disabled then you can fallback to URL rewriting to encode Session id e.g. JSESSIOINID into the URL itself.

Hidden Form fields
Similar to URL rewriting. The server embeds new hidden fields in every dynamically generated form page for the client. When the client submits the form to the server the hidden fields identify the client.

HTTPS and SSL
Web browsers that support Secure Socket Layer communication can use SSL’s support via HTTPS for generating a unique session key as part of the encrypted conversation. Modern days online internet banking website, ticket booking websites, e-commerce retailers like Amazon and e-bay all use HTTPS to security transfer data and manage the session.

Importing a Java Method in to JSP Page

package com.mugil.servlet;

public class Sample1 
{
  static int pincode = 600018;
  
  public String toString()
  {	
    return "600018";
  }
}
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ page import = "com.mugil.servlet.Sample1"%>    
 <body>
   <%=new Sample1()%>
 </body>

Note:
The following Code wont work

  <%=new Sample1();%>
  <% =new Sample1()%>