i tried to redirect the 400 error with my custom error page but its not working. 400 only not redirect, 404 and 500 its working fine
1:
<error-page>
<error-code>400</error-code>
<location>/faces/errors.xhtml</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/faces/notfound.xhtml</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/faces/error.xhtml</location>
</error-page>
2: changed in server level --sever.xml file its also not working
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.ErrorReportValve"
errorCode.400="/faces/errors.xhtml"
showReport="false"
showServerInfo="false" />
3 created the servelet class to redirect the error its also not working
package tneb.ccms.consumer;
import java.io.IOException;
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("/error400")
public class Error400Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Set response content type
//System.out.println( request.getRequestURI());
response.setContentType("text/html");
System.out.println("error page");
// Set response status to 400 Bad Request
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.sendRedirect(request.getContextPath()+"/faces/errors.xhtml");
}
}
package tneb.ccms.consumer;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.FilterRegistration;
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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class BadRequestFilter implements Filter {
private FilterConfig filterConfig;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
try {
chain.doFilter(request, response);
} catch (Exception e) {
if (httpResponse.getStatus() == HttpServletResponse.SC_BAD_REQUEST) {
httpRequest.getRequestDispatcher("/faces/errors.xhtml").forward(request, response);
} else {
throw e;
}
}
}
@Override
public void destroy() {
// Cleanup code if needed
}
}
if i encounter the 400 error in url it should not return the custom error page it shows normal tomcat page
http://localhost:11779/tangedco-public/%
I tried everything i know,created the standalone project and set the custom error and upgrade and downgraded the tomcatversion still i cant resolve the error!
hello-tomcat9-web
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── example
│ └── HelloStatusServlet.java
└── webapp
├── 400.html
├── 404.html
├── 500.html
├── index.jsp
└── WEB-INF
└── web.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>helloweb</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>helloweb</name>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>helloworld</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
Just set the corresponding web pages in web.xml - status code 400, 404, 500.
Please confirm the version of web.xml.
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
...
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>hello-tomcat9-web</display-name>
<error-page>
<error-code>400</error-code>
<location>/400.html</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.html</location>
</error-page>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
</web-app>
HelloStatusServlet can be used to simulate generating and returning 400 and 500 status codes.
package com.example;
import java.io.IOException;
import java.io.PrintWriter;
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("/helloStatus")
public class HelloStatusServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String errorType = request.getParameter("error");
if ("400".equals(errorType)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Simulated 400 Error");
return;
} else if ("500".equals(errorType)) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Simulated 500 Error");
return;
}
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>Hello, World!</h1><p/>");
out.println("<h1>Status TEST!</h1><p/>");
out.println("</body></html>");
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Hello Page</title>
</head>
<body>
<h1>Hello</h1>
<p>Current Date and Time: <%= new java.util.Date() %></p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Bad Request</title>
</head>
<body>
<h1>400 - Bad Request</h1>
<p>ZZZZZ - The request could not be understood by the server due to malformed syntax.</p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Page Not Found</title>
</head>
<body>
<h1>404 - Page Not Found</h1>
<p>ZZZZZ - The requested resource could not be found on this server.</p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Internal Server Error</title>
</head>
<body>
<h1>500 - Internal Server Error</h1>
<p>ZZZZZ - Sorry, something went wrong on our end. Please try again later.</p>
</body>
</html>
mvn clean package
put helloworld.war
to Tomcat/webapps/
return index.jsp
return helloStatus servlet.
Simulates a status code of 400.
Simulates a status code of 500.
return 404
http://localhost:8080/tangedco-public/%
show tomcat HTTP Status 400 – Bad Request
, not my 400 error page. FAIL.http://localhost:8080/tangedco-public/~
show my 404 error page.logs/catalina.out
12-Jul-2024 18:03:20.057 INFO [http-nio-8080-exec-8] org.apache.tomcat.util.http.Parameters.processParameters Character decoding failed. Parameter [%] with value [] has been ignored. Note that the name and value quoted here may be corrupted due to the failed decoding. Use debug level logging to see the original, non-corrupted values.
Note: further occurrences of Parameter errors will be logged at DEBUG level.
add URIEncoding="UTF-8"
<!--
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxParameterCount="1000"
/>
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxParameterCount="1000"
URIEncoding="UTF-8"
/>
same problem. not solve URI invalid character problem.
conf/logging.properties
org.apache.coyote.http11.Http11Processor.level = FINE
org.apache.tomcat.util.http.Parameters.level = FINE
shutdown tomcat
start tomcat
http://localhost:8080/tangedco-public/%
show tomcat HTTP Status 400 – Bad Request
, not my 400 error page. FAIL.http://localhost:8080/tangedco-public/~
show my 404 error page.logs/catalina.out
12-Jul-2024 18:23:59.711 XXXX [http-nio-8080-exec-8] org.apache.tomcat.util.http.Parameters.processParameters Character decoding failed. Parameter [%] with value [null] has been ignored.
org.apache.tomcat.util.buf.UDecoder$DecodeException: End of file (EOF)
12-Jul-2024 18:24:30.096 XXXX [http-nio-8080-exec-1] org.apache.coyote.http11.Http11Processor.service Error parsing HTTP request header
java.io.EOFException
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1343)
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1231)
at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:789)
at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:348)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:261)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:936)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:840)
12-Jul-2024 18:24:30.098 XXXX [http-nio-8080-exec-1] org.apache.coyote.AbstractProcessor.setErrorState Error state [CLOSE_CONNECTION_NOW] reported while processing request
java.io.EOFException
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1343)
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1231)
at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:789)
at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:348)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:261)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:936)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:840)
My inference is that when the request comes in, it will be processed first in org.apache.coyote.http11.Http11Processor.service, but when illegal characters are found, it will cause it to generate an org.apache.coyote.AbstractProcessor.setErrorState Error state [CLOSE_CONNECTION_NOW] reported while processing request
, leading to early termination and not sending the request to the scope of our own webapp level. In other words, our webapp has not received the request at all and has been sent to the tomcat server level in advance. Disposed of.
As for how to deal with this problem, this is a problem of how Tomcat handles illegal characters in URIs, so we need to seek answers to how Tomcat handles illegal characters.