package net.viralpatel.servlet.filter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionFilter implements Filter {
private ArrayList<String> urlList;
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getServletPath();
boolean allowedRequest = false;
if(urlList.contains(url)) {
allowedRequest = true;
}
if (!allowedRequest) {
HttpSession session = request.getSession(false);
if (null == session) {
response.sendRedirect("index.jsp");
}
}
chain.doFilter(req, res);
}
public void init(FilterConfig config) throws ServletException {
String urls = config.getInitParameter("avoid-urls");
StringTokenizer token = new StringTokenizer(urls, ",");
urlList = new ArrayList<String>();
while (token.hasMoreTokens()) {
urlList.add(token.nextToken());
}
}
}
Code language: Java (java)
The init() method will get called by the servlet container and will get FilterConfig object as arguement. From this config object, we read the init parameters. We will see shortly what parameters do we passed in filter. The doFilter() method will be called for each request of our application. Hence we can check the session in this method and see if it is valid. From init() method, we had generated a list of pages (urls) that were having access although the session is null. Index pages, error pages and other pages that you think user can access without logging in should be specified in this list. In doFilter() method, you will notice one response.sendRedirect. I have redirected my user to index.jsp page if session is not valid. You can give any landing URL that you want your user to go when session is not valid. Alternatively you may want to create a JSON response and send it to client if you think the request was originated from AJAX. <filter>
<filter-name>SessionFilter</filter-name>
<filter-class>
net.viralpatel.servlet.filter.SessionFilter
</filter-class>
<init-param>
<param-name>avoid-urls</param-name>
<param-value>index.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Code language: HTML, XML (xml)
We have specified the filter in web.xml file which will get called for url /*. You can configure the URL mapping like normal filters URL mapping. Also note that we have specified a parameter avoid-url in init-parameters of filter. The value of this parameter will be a comma separated paths that we do not want to apply session validations on. I have specified index.jsp, you can give more urls separated by comma. e.g. index.jsp, someAction.do, Request.jsp, Message.jsf Java URL Encoder/Decoder Example - In this tutorial we will see how to URL encode/decode…
Show Multiple Examples in OpenAPI - OpenAPI (aka Swagger) Specifications has become a defecto standard…
Local WordPress using Docker - Running a local WordPress development environment is crucial for testing…
1. JWT Token Overview JSON Web Token (JWT) is an open standard defines a compact…
GraphQL Subscription provides a great way of building real-time API. In this tutorial we will…
1. Overview Spring Boot Webflux DynamoDB Integration tests - In this tutorial we will see…
View Comments
Wouldn\'t you want a \"break\" statement after line 35?
With the current implementation it's a meaningless optimization, but if there were a number of non-session oriented pages you wouldn't want to continually do String compares when it doesn't change the result.
Thanks Corey.
I have updated the post and added the break statement. Certainly a break will be needed in order to skip unnecessary comparisons.
Based on J2EE javadoc, HttpServletRequest.getSession() will always return a session object. (If the session dose not already exists, it will create a new one). I think in line 41 you need to have HttpSession session = request.getSession(false);
Thanks Shahram for pointing out the error. I have modified the code and added HttpSession session = request.getSession(false); instead of HttpSession session = request.getSession();
Thanks again :)
it doesn,t works.
I have this exception :
java.lang.IllegalStateException: Cannot forward after response has been committed
Hi Dod,
Can you please paste your Filter code? The above code seems to be working for me.
The error you are getting comes when you try to do response.sendRedirect( ) after printing something in response. You may have some out.print () statements before the redirect.
Still I am not sure about the problem.
that's my code:
Ok, so the code seems to be working
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getServletPath();
String contextPath = request.getContextPath();
boolean allowedRequest = false;
for(int i=0; i<totalURLS; i++) {
if(url.contains(urlList.get(i))) {
allowedRequest = true;
break;
}
}
if (!allowedRequest) {
HttpSession session = request.getSession();
if (null == session) {
response.sendRedirect(contextPath+"/jsp/loginError.jsp");
}else{
String logged = (String) session.getAttribute("logged-in");
if (logged == null){
response.sendRedirect(contextPath+"/jsp/loginError.jsp");
}else{
chain.doFilter(request, response);
}
}
} else{
chain.doFilter(request, response);
}
}
Nice to see that your error got resolved :-)
I think the code HttpSession session = request.getSession(); needs to be replaced with HttpSession session = request.getSession(false); otherwise everytime a new session will get created.
Hi dod,
you've got an error in line 34, please remove the semicolon.
Additionally i get the "Cannot create a session after the response has been committed"-message, too, although i don't put anything in out?!
Any idea?
--------------
public class SessionFilter implements Filter {
private ArrayList urlList;
private int totalURLS;
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getServletPath();
boolean noSessionNeeded = false;
for(int i=0; i<totalURLS; i++) {
String pattern=urlList.get(i);
if(url.contains(pattern)) {
noSessionNeeded = true;
break;
}
}
if (!noSessionNeeded) {
HttpSession session = request.getSession(false);
boolean exists=(session!=null);
boolean isNew=session.isNew();
if(!exists) response.sendRedirect("index.jsp");
if(isNew) response.sendRedirect("index.jsp");
}
chain.doFilter(req, res);
}
public void init(FilterConfig config) throws ServletException {
String urls = config.getInitParameter("noSessionNeeded");
StringTokenizer token = new StringTokenizer(urls, ",");
urlList = new ArrayList();
while (token.hasMoreTokens()) {
urlList.add(token.nextToken());
}
totalURLS = urlList.size();
}
}
Add a return after the forward/redirect statement, this will remove the illegalArgumentException