After Request Filtering Why It Is Going to Filter Again Sprring Boot App
Why practice we have Servlet Filter?
In the last article, nosotros learned how we tin manage session in web application and if we want to make sure that a resource is accessible only when the user session is valid, we can achieve this using servlet session attributes. The approach is simple but if we have a lot of servlets and jsps, then it will become difficult to maintain because of redundant code. If we desire to change the attribute name in the future, we volition have to modify all the places where nosotros accept session authentication.
That's why we have a servlet filter. Servlet Filters are pluggable java components that we tin can utilise to intercept and procedure requests before they are sent to servlets and response after servlet code is finished and before container sends the response back to the client.
Some common tasks that nosotros can do with servlet filters are:
- Logging request parameters to log files.
- Authentication and autherization of request for resources.
- Formatting of request body or header before sending it to servlet.
- Compressing the response data sent to the client.
- Alter response by calculation some cookies, header information etc.
Equally I mentioned earlier, servlet filters are pluggable and configured in deployment descriptor (web.xml) file. Servlets and filters both are unaware of each other and nosotros can add or remove a servlet filter just past editing web.xml.
We can have multiple filters for a single resource and we can create a chain of filters for a unmarried resource in web.xml. We tin can create a Servlet Filter by implementing javax.servlet.Filter
interface.
Servlet Filter interface
Servlet Filter interface is similar to Servlet interface and nosotros need to implement information technology to create our own servlet filter. Servlet Filter interface contains lifecycle methods of a Filter and it's managed by servlet container.
Servlet Filter interface lifecycle methods are:
- void init(FilterConfig paramFilterConfig) – When container initializes the Filter, this is the method that gets invoked. This method is chosen only once in the lifecycle of filter and we should initialize whatever resources in this method. FilterConfig is used by container to provide init parameters and servlet context object to the Filter. Nosotros tin throw ServletException in this method.
- doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse, FilterChain paramFilterChain) – This is the method invoked every time by container when it has to apply filter to a resource. Container provides asking and response object references to filter as argument. FilterChain is used to invoke the next filter in the chain. This is a great example of Concatenation of Responsibility Pattern.
- void destroy() – When container offloads the Filter instance, it invokes the destroy() method. This is the method where we can shut whatever resource opened by filter. This method is called but once in the lifetime of filter.
Servlet WebFilter note
javax.servlet.annotation.WebFilter
was introduced in Servlet 3.0 and nosotros can utilize this annotation to declare a servlet filter. We can use this notation to define init parameters, filter proper name and description, servlets, url patterns and dispatcher types to apply the filter. If you brand frequent changes to the filter configurations, its better to use web.xml because that will not require you to recompile the filter form.
Read: Java Annotations Tutorial
Servlet Filter configuration in web.xml
We tin can declare a servlet filter in spider web.xml like below.
<filter> <filter-name>RequestLoggingFilter</filter-name> <!-- mandatory --> <filter-class>com.journaldev.servlet.filters.RequestLoggingFilter</filter-class> <!-- mandatory --> <init-param> <!-- optional --> <param-proper noun>test</param-name> <param-value>testValue</param-value> </init-param> </filter>
We can map a Filter to servlet classes or url-patterns like below.
<filter-mapping> <filter-name>RequestLoggingFilter</filter-name> <!-- mandatory --> <url-pattern>/*</url-blueprint> <!-- either url-pattern or servlet-proper noun is mandatory --> <servlet-name>LoginServlet</servlet-name> <dispatcher>Asking</dispatcher> </filter-mapping>
Note: While creating the filter chain for a servlet, container commencement processes the url-patterns and then servlet-names, so if you accept to make certain that filters are getting executed in a particular club, give extra attention while defining the filter mapping.
Servlet Filters are generally used for client requests but sometimes we want to use filters with RequestDispatcher also, we can use dispatcher element in this case, the possible values are Request, FORWARD, INCLUDE, ERROR and ASYNC. If no dispatcher is defined then it's applied merely to client requests.
Servlet Filter Instance for Logging and session validation
In our servlet filter example, we will create filters to log request cookies and parameters and validate session to all the resources except static HTMLs and LoginServlet because it will not have a session.
We will create a dynamic web projection ServletFilterExample whose projection structure will expect similar the below epitome.
login.html is the entry signal of our application where the user will provide the login id and password for authentication.
login.html code:
<!DOCTYPE html> <html> <head> <meta charset="United states of america-ASCII"> <title>Login Folio</title> </head> <body> <form action="LoginServlet" method="post"> Username: <input type="text" proper noun="user"> <br> Password: <input blazon="password" name="pwd"> <br> <input type="submit" value="Login"> </form> </body> </html>
LoginServlet is used to cosign the request from the client for login.
package com.journaldev.servlet.session; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * Servlet implementation class LoginServlet */ @WebServlet("/LoginServlet") public class LoginServlet extends HttpServlet { individual static final long serialVersionUID = 1L; private final String userID = "admin"; private final String password = "password"; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // get asking parameters for userID and password String user = request.getParameter("user"); Cord pwd = request.getParameter("pwd"); if(userID.equals(user) && password.equals(pwd)){ HttpSession session = request.getSession(); session.setAttribute("user", "Pankaj"); //setting session to death in xxx mins session.setMaxInactiveInterval(xxx*60); Cookie userName = new Cookie("user", user); userName.setMaxAge(30*60); response.addCookie(userName); response.sendRedirect("LoginSuccess.jsp"); }else{ RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html"); PrintWriter out= response.getWriter(); out.println("<font color=red>Either user proper name or password is wrong.</font>"); rd.include(request, response); } } }
When the client is authenticated, it'due south forwarded to LoginSuccess.jsp
LoginSuccess.jsp code:
<%@ page language="java" contentType="text/html; charset=US-ASCII" pageEncoding="US-ASCII"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=U.s.-ASCII"> <title>Login Success Page</title> </caput> <body> <% //allow access only if session exists Cord user = (Cord) session.getAttribute("user"); String userName = naught; Cord sessionID = null; Cookie[] cookies = request.getCookies(); if(cookies !=null){ for(Cookie cookie : cookies){ if(cookie.getName().equals("user")) userName = cookie.getValue(); if(cookie.getName().equals("JSESSIONID")) sessionID = cookie.getValue(); } } %> <h3>Hi <%=userName %>, Login successful. Your Session ID=<%=sessionID %></h3> <br> User=<%=user %> <br> <a href="CheckoutPage.jsp">Checkout Page</a> <form action="LogoutServlet" method="post"> <input type="submit" value="Logout" > </form> </body> </html>
Detect that there is no session validation logic in the above JSP. It contains a link to some other JSP page, CheckoutPage.jsp.
CheckoutPage.jsp lawmaking:
<%@ page language="java" contentType="text/html; charset=US-ASCII" pageEncoding="Us-ASCII"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML four.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Blazon" content="text/html; charset=US-ASCII"> <title>Login Success Page</title> </head> <body> <% String userName = null; String sessionID = naught; Cookie[] cookies = request.getCookies(); if(cookies !=null){ for(Cookie cookie : cookies){ if(cookie.getName().equals("user")) userName = cookie.getValue(); } } %> <h3>Hi <%=userName %>, practice the checkout.</h3> <br> <class action="LogoutServlet" method="mail"> <input type="submit" value="Logout" > </form> </trunk> </html>
LogoutServlet is invoked when a client clicks on the Logout button in whatever of the JSP pages.
packet com.journaldev.servlet.session; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * Servlet implementation class LogoutServlet */ @WebServlet("/LogoutServlet") public class LogoutServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); Cookie[] cookies = request.getCookies(); if(cookies != null){ for(Cookie cookie : cookies){ if(cookie.getName().equals("JSESSIONID")){ Organization.out.println("JSESSIONID="+cookie.getValue()); break; } } } //invalidate the session if exists HttpSession session = request.getSession(simulated); System.out.println("User="+session.getAttribute("user")); if(session != null){ session.invalidate(); } response.sendRedirect("login.html"); } }
Now we volition create logging and authentication servlet filter classes.
bundle com.journaldev.servlet.filters; import java.io.IOException; import java.util.Enumeration; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; /** * Servlet Filter implementation class RequestLoggingFilter */ @WebFilter("/RequestLoggingFilter") public class RequestLoggingFilter implements Filter { individual ServletContext context; public void init(FilterConfig fConfig) throws ServletException { this.context = fConfig.getServletContext(); this.context.log("RequestLoggingFilter initialized"); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; Enumeration<String> params = req.getParameterNames(); while(params.hasMoreElements()){ String proper noun = params.nextElement(); String value = request.getParameter(name); this.context.log(req.getRemoteAddr() + "::Request Params::{"+name+"="+value+"}"); } Cookie[] cookies = req.getCookies(); if(cookies != naught){ for(Cookie cookie : cookies){ this.context.log(req.getRemoteAddr() + "::Cookie::{"+cookie.getName()+","+cookie.getValue()+"}"); } } // pass the request forth the filter chain chain.doFilter(request, response); } public void destroy() { //we can close resources hither } }
package com.journaldev.servlet.filters; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.note.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @WebFilter("/AuthenticationFilter") public course AuthenticationFilter implements Filter { private ServletContext context; public void init(FilterConfig fConfig) throws ServletException { this.context = fConfig.getServletContext(); this.context.log("AuthenticationFilter initialized"); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; Cord uri = req.getRequestURI(); this.context.log("Requested Resources::"+uri); HttpSession session = req.getSession(false); if(session == null && !(uri.endsWith("html") || uri.endsWith("LoginServlet"))){ this.context.log("Unauthorized access request"); res.sendRedirect("login.html"); }else{ // pass the request along the filter concatenation chain.doFilter(request, response); } } public void destroy() { //close whatever resource hither } }
Notice that we are non authenticating any HTML page or LoginServlet. Now we will configure these filters mapping in the spider web.xml file.
<?xml version="1.0" encoding="UTF-8"?> <spider web-app xmlns:xsi="https://world wide web.w3.org/2001/XMLSchema-instance" xmlns="https://coffee.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sunday.com/xml/ns/javaee/web-app_3_0.xsd" version="three.0"> <display-name>ServletFilterExample</brandish-name> <welcome-file-list> <welcome-file>login.html</welcome-file> </welcome-file-list> <filter> <filter-name>RequestLoggingFilter</filter-proper name> <filter-class>com.journaldev.servlet.filters.RequestLoggingFilter</filter-class> </filter> <filter> <filter-name>AuthenticationFilter</filter-proper name> <filter-grade>com.journaldev.servlet.filters.AuthenticationFilter</filter-class> </filter> <filter-mapping> <filter-name>RequestLoggingFilter</filter-name> <url-design>/*</url-pattern> <dispatcher>Request</dispatcher> </filter-mapping> <filter-mapping> <filter-proper noun>AuthenticationFilter</filter-proper noun> <url-design>/*</url-pattern> </filter-mapping> </spider web-app>
Now when we will run our application, we will get response pages like below images.
If y'all are not logged in and effort to access any JSP page, yous will exist forwarded to the login folio.
In the server log file, yous can come across the logs written past servlet filters likewise as servlets.
Aug 13, 2013 one:06:07 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A} Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resources::/ServletFilterExample/ Aug 13, 2013 1:06:07 AM org.apache.catalina.cadre.ApplicationContext log INFO: Unauthorized admission request Aug 13, 2013 one:06:07 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A} Aug xiii, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/login.html Aug thirteen, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Request Params::{pwd=password} Aug 13, 2013 ane:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Request Params::{user=admin} Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:ane%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A} Aug 13, 2013 i:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/LoginServlet Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:i%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} Aug 13, 2013 1:06:43 AM org.apache.catalina.cadre.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp Aug thirteen, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug 13, 2013 i:06:52 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:one%0::Cookie::{user,admin} Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resources::/ServletFilterExample/CheckoutPage.jsp Aug 13, 2013 one:07:00 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} Aug 13, 2013 1:07:00 AM org.apache.catalina.cadre.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/LogoutServlet JSESSIONID=8BDF777933194EDCAC1D8F1B73633C56 User=Pankaj Aug 13, 2013 ane:07:00 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug xiii, 2013 1:07:00 AM org.apache.catalina.cadre.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/login.html Aug 13, 2013 1:07:06 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp Aug thirteen, 2013 1:07:07 AM org.apache.catalina.cadre.ApplicationContext log INFO: Unauthorized access request Aug 13, 2013 ane:07:07 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:one%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug xiii, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} Aug xiii, 2013 1:07:07 AM org.apache.catalina.cadre.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/login.html
Source: https://www.journaldev.com/1933/java-servlet-filter-example-tutorial
0 Response to "After Request Filtering Why It Is Going to Filter Again Sprring Boot App"
Post a Comment