Made a test web application with 3 pages: login.xhtml , registr.xhtml and index.xhtml . 2 servlets: LoginServlet and RegistrServlet , which are responsible for user login and registration, respectively. Also added a web filter: LoginFilter , which checks if the user is authenticated. If not and is not on the login.xhtml page, the filter redirects the user to this page.

Project structure:

 LoginWithServlet Web Pages WEB-INF web.xml login.xhtml registr.xhtml index.xhtml Source Packages classes User.java Database.java filters LoginFilter.java servlets LoginServlet.java RegistrServlet.java 

Servlets and filter:

 @WebServlet(name = "LoginServlet", urlPatterns = {"/login"}) public class LoginServlet extends HttpServlet { private static final Logger logger = Logger.getLogger(LoginServlet.class.getName()); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher(request.getContextPath() + "/login.xhtml").forward(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext ctx = request.getServletContext(); String login = (String) request.getParameter("login"); String password = (String) request.getParameter("password"); Database database = Database.getInstance(); User user = database.find(login, password); if (user == null) { // request.getRequestDispatcher(request.getContextPath() + "/registr").forward(request, response); ctx.log("Incorrect login or password"); response.sendRedirect(request.getContextPath() + "/registr"); } else { ctx.log(String.format("User %s has logged in", user)); request.getSession().setAttribute("user", user); request.getRequestDispatcher(request.getContextPath() + "/index.xhtml").forward(request, response); } } } @WebServlet(name = "RegistrServlet", urlPatterns = {"/registr"}) public class RegistrServlet extends HttpServlet { private static final Logger logger = Logger.getLogger(RegistrServlet.class.getName()); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher(request.getContextPath() + "/registr.xhtml").forward(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext ctx = request.getServletContext(); Long id = Long.valueOf(request.getParameter("id")); String login = (String) request.getParameter("login"); String password = (String) request.getParameter("password"); User user = new User(id, login, password); Database database = Database.getInstance(); boolean inserted = database.insert(user); if(inserted) { ctx.log(String.format("New user %s has registred", user)); request.getSession().setAttribute("user", user); request.getRequestDispatcher(request.getContextPath() + "/index.xhtml").forward(request, response); } else { ctx.log("Such user already exists"); } } @Override public String getServletInfo() { return "Short description"; } } @WebFilter("/*") public class LoginFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; HttpSession session = req.getSession(false); String loginURI = req.getContextPath() + "/login"; boolean loggedIn = session != null && session.getAttribute("user") != null; boolean loginRequest = req.getRequestURI().equals(loginURI); if(loggedIn || loginRequest) { chain.doFilter(request, response); } else { res.sendRedirect(loginURI); } } } 

Start page: index.xhtml

The sequence of actions when starting this application (as I imagine):

  1. The user makes a request for the index.xhtml ;
  2. Since the user is not yet authenticated, LoginFilter redirects him to the loginURI = req.getContextPath() + "/login" (this URL handles the LoginServlet servlet);
  3. In the LoginServlet servlet, the doGet method is invoked;
  4. The doGet method directs the user to the login.xhtml page;
  5. It depends on whether such a user is in the database: if yes, then the user is directed to the index.xhtml ; if not, by the URL request.getContextPath() + "/registr" , which handles the RegistrServlet servlet.

It seems everything is beautiful, but there is one thing. Immediately at startup, I get an error with code 404 and the message:

/LoginWithServlet/login.xhtml Not Found in ExternalContext as a Resource

I tried to change loginURI in LoginFilter to loginURI = req.getContextPath() + "/login.xhtml" (instead of "/ login" wrote "/login.xhtml") and the filter successfully redirected to the login.xhtml page. But the trouble is, when trying to enter any data (existing and not), I remain on the login.xhtml page.

Thank you in advance!

  • Filter does not let? - Roman C
  • @RomanC, I have already fixed everything myself)) Yes, it was necessary to add a condition in the filter: if the user is on the registration page, then there is no need to redirect. And the error was due to the fact that the URL was not correctly written. I did not know that the contextual path appends the web container and it is not part of the URL. Removed request.getContextPath() and everything works) - not a Programmer

0