Spring 中的 404 错误(java config / no web.xml)

尝试在 Web 应用程序中提供自定义 404 错误页面,据我所知,该页面使用 Java Config(因此没有 web.xml)。

我们有以下版本的相关库:spring ("5.1.2.RELEASE")、spring-security ("5.1.1.RELEASE")。

免责声明

我在 StackOverflow 中检查了不同的方法。请不要为 web.xml、Thymeleaf 或 Spring Boot 推荐结果。这不适用。

其中; 我尝试了以下方法:

没有产生预期的结果(即,仍然得到默认的网络服务器布局和错误)。


红颜莎娜
浏览 164回答 3
3回答

德玛西亚99

虽然没有我想的那么清楚,但这是一种工作版本,至少可以为错误页面提供一些自定义。这是第一种方法,但希望可以帮助其他人。处理的异常列表并不广泛,但主要解决 404 错误 ( NoHandlerFoundException) 和其他典型错误,例如InternalServerErrorExceptionand NullPointerException,尝试在最后捕获所有异常,并为所有其他是 a 的错误提供通用错误Exception)。请注意,这不包括与例如 JSTL 模板中的错误语法相关的其他异常(org.apache.jasper.*; 显然无法在此处捕获的异常)。这些是源库的相关更改和添加:CustomSimpleMappingExceptionResolver.java(提供通用异常,但记录详细信息)package ...;import java.util.ArrayList;import java.util.Arrays;import java.util.Date;import javax.ws.rs.InternalServerErrorException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.http.HttpStatus;import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.NoHandlerFoundException;public class CustomSimpleMappingExceptionResolver extends SimpleMappingExceptionResolver {&nbsp; &nbsp; public CustomSimpleMappingExceptionResolver() {&nbsp; &nbsp; &nbsp; &nbsp; // Turn logging on by default&nbsp; &nbsp; &nbsp; &nbsp; setWarnLogCategory(getClass().getName());&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public String buildLogMessage(Exception e, HttpServletRequest req) {&nbsp; &nbsp; &nbsp; &nbsp; return "MVC exception: " + e.getLocalizedMessage();&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Object handler, Exception ex) {&nbsp; &nbsp; &nbsp; &nbsp; // Log exception&nbsp; &nbsp; &nbsp; &nbsp; ex.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; String exceptionCause = ex.toString();&nbsp; &nbsp; &nbsp; &nbsp; String exceptionType = ex.getClass().getCanonicalName();&nbsp; &nbsp; &nbsp; &nbsp; // Get the ModelAndView to use&nbsp; &nbsp; &nbsp; &nbsp; ModelAndView mav = super.doResolveException(request, response, handler, ex);&nbsp; &nbsp; &nbsp; &nbsp; // Make more information available to the view - note that SimpleMappingExceptionResolver adds the exception already&nbsp; &nbsp; &nbsp; &nbsp; mav.addObject("url", request.getRequestURL());&nbsp; &nbsp; &nbsp; &nbsp; mav.addObject("timestamp", new Date());&nbsp; &nbsp; &nbsp; &nbsp; ArrayList<String> exceptions404 = new ArrayList<String>(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Arrays.asList(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NoHandlerFoundException.class.getName()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; ArrayList<String> exceptions500 = new ArrayList<String>(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Arrays.asList(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; InternalServerErrorException.class.getName(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NullPointerException.class.getName()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; String userExceptionDetail = ex.toString();&nbsp; &nbsp; &nbsp; &nbsp; String errorHuman = "";&nbsp; &nbsp; &nbsp; &nbsp; String errorTech = "";&nbsp; &nbsp; &nbsp; &nbsp; if (exceptions404.contains(exceptionType)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errorHuman = "We cannot find the page you are looking for";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errorTech = "Page not found";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userExceptionDetail = String.format("The page %s cannot be found", request.getRequestURL());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mav.setViewName("/error/404");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mav.addObject("status", HttpStatus.NOT_FOUND.value());&nbsp; &nbsp; &nbsp; &nbsp; } else if (exceptions500.contains(exceptionType)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errorHuman = "We cannot currently serve the page you request";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errorTech = "Internal error";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userExceptionDetail = "The current page refuses to load due to an internal error";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mav.setViewName("/error/500");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mav.addObject("status", HttpStatus.INTERNAL_SERVER_ERROR.value());&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errorHuman = "We cannot serve the current page";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errorTech = "General error";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userExceptionDetail = "A generic error prevents from serving the page";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mav.setViewName("/error/generic");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mav.addObject("status", response.getStatus());&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; Exception userException = new Exception(userExceptionDetail);&nbsp; &nbsp; &nbsp; &nbsp; mav.addObject("error_human", errorHuman);&nbsp; &nbsp; &nbsp; &nbsp; mav.addObject("error_tech", errorTech);&nbsp; &nbsp; &nbsp; &nbsp; mav.addObject("exception", userException);&nbsp; &nbsp; &nbsp; &nbsp; return mav;&nbsp; &nbsp; }}WebAppConfig.java(将自定义异常解析器注册为异常处理程序)package ...;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;import org.springframework.context.annotation.Scope;import org.springframework.context.annotation.ScopedProxyMode;import org.springframework.core.env.Environment;import org.springframework.core.Ordered;import org.springframework.http.HttpStatus;import org.springframework.transaction.annotation.EnableTransactionManagement;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.servlet.HandlerExceptionResolver;import org.springframework.web.servlet.NoHandlerFoundException;import org.springframework.web.servlet.view.InternalResourceViewResolver;import java.lang.ClassNotFoundException;import java.lang.NullPointerException;import javax.annotation.Resource;import javax.ws.rs.InternalServerErrorException;import java.util.Properties;@Configuration@ComponentScan("...")@EnableWebMvc@EnableTransactionManagement@PropertySource("classpath:application.properties")public class WebAppConfig extends WebMvcConfigurerAdapter {&nbsp; &nbsp; @Resource&nbsp; &nbsp; private Environment env;&nbsp; &nbsp; // ...&nbsp; &nbsp; @Bean&nbsp; &nbsp; HandlerExceptionResolver customExceptionResolver () {&nbsp; &nbsp; &nbsp; &nbsp; CustomSimpleMappingExceptionResolver resolver = new CustomSimpleMappingExceptionResolver();&nbsp; &nbsp; &nbsp; &nbsp; Properties mappings = new Properties();&nbsp; &nbsp; &nbsp; &nbsp; // Mapping Spring internal error NoHandlerFoundException to a view name&nbsp; &nbsp; &nbsp; &nbsp; mappings.setProperty(NoHandlerFoundException.class.getName(), "/error/404");&nbsp; &nbsp; &nbsp; &nbsp; mappings.setProperty(InternalServerErrorException.class.getName(), "/error/500");&nbsp; &nbsp; &nbsp; &nbsp; mappings.setProperty(NullPointerException.class.getName(), "/error/500");&nbsp; &nbsp; &nbsp; &nbsp; mappings.setProperty(ClassNotFoundException.class.getName(), "/error/500");&nbsp; &nbsp; &nbsp; &nbsp; mappings.setProperty(Exception.class.getName(), "/error/generic");&nbsp; &nbsp; &nbsp; &nbsp; resolver.setExceptionMappings(mappings);&nbsp; &nbsp; &nbsp; &nbsp; // Set specific HTTP codes&nbsp; &nbsp; &nbsp; &nbsp; resolver.addStatusCode("404", HttpStatus.NOT_FOUND.value());&nbsp; &nbsp; &nbsp; &nbsp; resolver.addStatusCode("500", HttpStatus.INTERNAL_SERVER_ERROR.value());&nbsp; &nbsp; &nbsp; &nbsp; resolver.setDefaultErrorView("/error/generic");&nbsp; &nbsp; &nbsp; &nbsp; resolver.setDefaultStatusCode(200);&nbsp; &nbsp; &nbsp; &nbsp; // This resolver will be processed before the default ones&nbsp; &nbsp; &nbsp; &nbsp; resolver.setOrder(Ordered.HIGHEST_PRECEDENCE);&nbsp; &nbsp; &nbsp; &nbsp; resolver.setExceptionAttribute("exception");&nbsp; &nbsp; &nbsp; &nbsp; return resolver;&nbsp; &nbsp; }&nbsp; &nbsp; // ...&nbsp; &nbsp; @Bean&nbsp; &nbsp; public InternalResourceViewResolver setupViewResolver() {&nbsp; &nbsp; &nbsp; &nbsp; InternalResourceViewResolver resolver = new InternalResourceViewResolver();&nbsp; &nbsp; &nbsp; &nbsp; resolver.setPrefix("/WEB-INF/views");&nbsp; &nbsp; &nbsp; &nbsp; resolver.setSuffix(".jsp");&nbsp; &nbsp; &nbsp; &nbsp; resolver.setExposeContextBeansAsAttributes(true);&nbsp; &nbsp; &nbsp; &nbsp; return resolver;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public void addViewControllers(ViewControllerRegistry registry) {&nbsp; &nbsp; &nbsp; &nbsp; super.addViewControllers(registry);&nbsp; &nbsp; }}Initializer.java(添加dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);;可能不需要)package ...;import org.springframework.web.WebApplicationInitializer;import org.springframework.web.context.ContextLoaderListener;import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.servlet.DispatcherServlet;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRegistration;public class Initializer implements WebApplicationInitializer {&nbsp; &nbsp; public void onStartup(ServletContext servletContext) throws ServletException {&nbsp; &nbsp; &nbsp; &nbsp; AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();&nbsp; &nbsp; &nbsp; &nbsp; ctx.register(WebAppConfig.class);&nbsp; &nbsp; &nbsp; &nbsp; servletContext.addListener(new ContextLoaderListener(ctx));&nbsp; &nbsp; &nbsp; &nbsp; ctx.setServletContext(servletContext);&nbsp; &nbsp; &nbsp; &nbsp; DispatcherServlet dispatcherServlet = new DispatcherServlet(ctx);&nbsp; &nbsp; &nbsp; &nbsp; dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);&nbsp; &nbsp; &nbsp; &nbsp; // Add the dispatcher servlet mapping manually and make it initialize automatically&nbsp; &nbsp; &nbsp; &nbsp; ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", dispatcherServlet);&nbsp; &nbsp; &nbsp; &nbsp; servlet.addMapping("/");&nbsp; &nbsp; &nbsp; &nbsp; servlet.addMapping("*.png");&nbsp; &nbsp; &nbsp; &nbsp; servlet.addMapping("*.jpg");&nbsp; &nbsp; &nbsp; &nbsp; servlet.addMapping("*.css");&nbsp; &nbsp; &nbsp; &nbsp; servlet.addMapping("*.js");&nbsp; &nbsp; &nbsp; &nbsp; servlet.addMapping("*.txt");&nbsp; &nbsp; &nbsp; &nbsp; servlet.setLoadOnStartup(1);&nbsp; &nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; }}与错误类相关的视图和标签的结构:&nbsp; &nbsp; src/main/webapp/WEB-INF/&nbsp; &nbsp; ├── tags&nbsp; &nbsp; │&nbsp; &nbsp;└── error.tag&nbsp; &nbsp; └── views&nbsp; &nbsp; &nbsp; &nbsp; ├── error&nbsp; &nbsp; &nbsp; &nbsp; │&nbsp; &nbsp;├── 404.jsp&nbsp; &nbsp; &nbsp; &nbsp; │&nbsp; &nbsp;├── 500.jsp&nbsp; &nbsp; &nbsp; &nbsp; └────── generic.jspsrc/main/webapp/WEB-INF/tags/error.tag<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><!DOCTYPE html><head>&nbsp; &nbsp; <title>Error page</title></head><body><div class="container">&nbsp; &nbsp; <h3><c:out value="${error_human}" /></h3>&nbsp; &nbsp; <p><br/><br/></p>&nbsp; &nbsp; <div class="panel panel-primary">&nbsp; &nbsp; &nbsp; &nbsp; <div class="panel-heading">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <c:out value="${error_tech}" />&nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; &nbsp; <div class="panel-body">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <p><c:out value="${exception_message}" /></p>&nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; </div></div></body></html>src/main/webapp/WEB-INF/views/error/404.jsp<%@ page language="java" contentType="text/html; charset=utf-8"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pageEncoding="utf-8" isErrorPage="true" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib tagdir="/WEB-INF/tags/" prefix="g" %><c:set var = "error_human" scope = "session" value = "We cannot find the page you are looking for"/><c:set var = "error_tech" scope = "session" value = "Page not found"/><c:set var = "exception_message" scope = "session" value = "The current page cannot be found"/><g:error />src/main/webapp/WEB-INF/views/error/500.jsp<%@ page language="java" contentType="text/html; charset=utf-8"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pageEncoding="utf-8" isErrorPage="true" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib tagdir="/WEB-INF/tags/" prefix="g" %><c:set var = "error_human" scope = "session" value = "We cannot currently serve the page you request"/><c:set var = "error_tech" scope = "session" value = "Internal error"/><c:set var = "exception_message" scope = "session" value = "The current page refuses to load due to an internal error"/><g:error />src/main/webapp/WEB-INF/views/error/generic.jsp<%@ page language="java" contentType="text/html; charset=utf-8"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pageEncoding="utf-8" isErrorPage="true" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib tagdir="/WEB-INF/tags/" prefix="g" %><c:set var = "error_human" scope = "session" value = "We cannot serve the current page"/><c:set var = "error_tech" scope = "session" value = "General error"/><c:set var = "exception_message" scope = "session" value = "A generic error prevents from serving the page"/><g:error />

斯蒂芬大帝

阅读 Spring Boot 文档,这对我有用:&nbsp; @Bean&nbsp; &nbsp;public ErrorPageRegistrar errorPageRegistrar() {&nbsp; &nbsp; &nbsp;return registry -> registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/index.html"));&nbsp; }这相当于 web.xml。

慕桂英546537

确保您可以访问 404 页面,然后添加这些代码。@ControllerAdvicepublic class GlobalExceptionHandler {&nbsp; &nbsp; @ResponseStatus(HttpStatus.NOT_FOUND)&nbsp; &nbsp; @ExceptionHandler(NoHandlerFoundException.class)&nbsp; &nbsp; public String handle404(Model model, HttpServletRequest req, Exception ex) {&nbsp; &nbsp; &nbsp; &nbsp; return "/404";&nbsp; &nbsp; }}应用程序.yamlspring:&nbsp; mvc:&nbsp; &nbsp; throwExceptionIfNoHandlerFound: true # if page not found, it will throw error, and then ControllerAdvice will catch the error.PS:springBoot版本=2.4.2;爪哇=15
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java