java – 404 error directed/or not to Servlet. Problems with Dispatcher

Question:

I'm studying java for web (EE) and would like to know if you guys could help solve a java problem!

I have in my web.xml a call to the error404.jsp file that is at the root of the site to filter pages that don't exist!

It turns out that if the called non-existent page is also at the root, for example /site/paginaInexiste.jsp, it will be at the same level as error404.jsp and when error404.jsp is called, all its internal links (css, includes[code ]) will work.

However, when the Nonexistent Page is inside any folder at the root, that is, outside the level of error404.jsp, example /site/pasta/paginaInexistente.jsp , then error404.jsp is called normally but its internal links do not work.

I tried sending 404 errors to a Servlet and the same perform RequestDispatcher to call error404.jsp because both Servlet and error404.jsp are at the same level, but it didn't work!

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>imwsaogotardo</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>AdminServlet</servlet-name>
    <servlet-class>imwsaogotardo.src.controller.AdminServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>AdminServlet</servlet-name>
    <url-pattern>/imwsaogotardo/AdminServlet</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>ProfessorServlet</servlet-name>
    <servlet-class>imwsaogotardo.src.controller.ProfessorServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ProfessorServlet</servlet-name>
    <url-pattern>/imwsaogotardo/ProfessorServlet</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>SalaServlet</servlet-name>
    <servlet-class>imwsaogotardo.src.controller.SalaServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>SalaServlet</servlet-name>
    <url-pattern>/imwsaogotardo/SalaServlet</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>UsuarioServlet</servlet-name>
    <servlet-class>imwsaogotardo.src.controller.UsuarioServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UsuarioServlet</servlet-name>
    <url-pattern>/imwsaogotardo/UsuarioServlet</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>PerguntaServlet</servlet-name>
    <servlet-class>imwsaogotardo.src.dao.pergunta.PerguntaServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>PerguntaServlet</servlet-name>
    <url-pattern>/imwsaogotardo/PerguntaServlet</url-pattern>
  </servlet-mapping>

  <error-page>
    <error-code>404</error-code>
    <location>/ErrosServlet</location>
  </error-page>
  <error-page>
    <error-code>500</error-code>
    <location>/ErrosServlet</location>
  </error-page>
</web-app>

It's on Servlet

package erros;

import java.io.IOException;


import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(
            name="ErrosServlet", 
            urlPatterns={"/ErrosServlet"}
           )
public class ErrosServlet extends HttpServlet 
{
    private static final long serialVersionUID = 1L;

    public ErrosServlet()
    {
        super();
    }

    public void doPost(HttpServletRequest req, HttpServletResponse res)    throws ServletException, IOException
    {
        Throwable throwable = (Throwable) req.getAttribute("javax.servlet.error.exception");
        Integer statusCode = (Integer) req.getAttribute("javax.servlet.error.status_code");

        req.setAttribute("errorType", throwable);
        req.setAttribute("statusCode", statusCode);

        //colocando o setStatus OK
        res.setStatus(HttpServletResponse.SC_OK);

        // We have to remove the exception from the request. If we do not remove the IE9 will not display out error page.
        // IE9 will think that some error created a crash inside our application if we do not remove the exception from the request.
        req.setAttribute("javax.servlet.error.exception", null);
        req.setAttribute("javax.servlet.error.status_code", null);

        RequestDispatcher requestDispatcher = null;

        if(statusCode==404)
        {
            requestDispatcher = req.getRequestDispatcher("/erro404.jsp");
        }
        else if(statusCode==500)
        {
            requestDispatcher = req.getRequestDispatcher("/erro500.jsp");
        }

        requestDispatcher.forward(req, res);    

    }

    public void doGet(HttpServletRequest req, HttpServletResponse res)    throws ServletException, IOException
    {
        doPost(req, res);
    }   
}

Note: I didn't launch Servet on web.xml

Is there any other feature?

Adding the error page:

<jsp:useBean id="constantes" class="util.Constantes" />     
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>    
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link type="text/css" href="_global/_css/estiloSite.css" />
<title>${constantes.tituloSite}</title>
</head>
<body class="fadeIn">

 <div id="topo"> <jsp:include page="_global/topoErro.jsp" /> </div>
 <div id="meio"> <jsp:include page="erro404Conteudo.jsp" /> </div>
 <div id="mapa"> <jsp:include page="_global/mapaErro.jsp" /> </div>
 <div id="creditos"> <jsp:include page="_global/creditosErro.jsp" /> </div>

 </body>
</html>

The following error404Content.jsp

<div id="central">

        Esta página não existe! <br/>
        Código do Erro : ${statusCode} <br/>
        <img src="_img/editar.png">
        <a href="_global/topoErro.jsp">Editar</a>
        <jsp:include page="_global/topoErro.jsp" />

</div>

Well, remembering that the dispatcher is done naturally. The error is only due to style and image links. The hrefs and includes occur normally!

Answer:

I don't know how your project is doing and what I suggest is a way to solve it, not necessarily the most elegant one.

As you didn't post your page with the links that aren't working, I assume that you are either using fixed paths OR relative paths, always starting with the current path, which in certain cases will give an error.

How to solve? You should always consider the context of your application when composing links, so that you always have the complete link to your resource, making the reference to the resource direct and non-reporting, in the same folder, etc. To do this you can do it in several ways, like these:

  • JSTL: if you are using JSTL you can do something like this:
<!-- recupera caminho do contexto e configura uma variável com este valor -->
<c:set var="ctx" value="${pageContext.request.contextPath}" scope="request" />

<!-- usa a variável -->
<a href="${ctx}/site/pagina.jsp" />
  • Using JSP scriptlet : if you're not using JSTL, you can do something less friendly, recovering something like this:
<!-- recupera caminho do contexto e configura uma variável com este valor -->
<%
String ctx = request.getContextPath();
%>

<!-- usa a variável -->
<a href="<%=ctx%>/site/pagina.jsp" />

Or directly:

<a href="<%=request.getContextPath()%>/site/pagina.jsp" />
Scroll to Top
AllEscort