试图在Web应用程序中提供自定义404错误页面,据我所知,该应用程序使用Java配置(因此没有web.xml)。
我们有以下版本的相关库:Spring("5.1.2. RELEASE")、sping-Security("5.1.1. RELEASE")。
我在StackOverflow中检查了这里的不同方法。请不要建议web.xml、Thymeleaf或Spring Boot的结果。这不适用。
其中;我尝试了以下方法:
@Controller
注释(这里和这里)没有生成预期的结果(也就是说,仍然得到默认的Web服务器布局和错误)。
>
package ...;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.NoHandlerFoundException;
@ControllerAdvice
public class GlobalExceptionHandler {
// Option A (used as an alternative to option B)
//@ExceptionHandler(Exception.class)
//public String handle(Exception ex) {
// return "redirect:/404";
//}
@RequestMapping(value = {"/404"}, method = RequestMethod.GET)
public String NotFoundPage() {
return "404";
}
// Option B (used as an alternative to option A)
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleNoHandlerFoundException(GlobalExceptionHandler ex) {
ResponseEntity responseEntity = new ResponseEntity<>(new RestClientException("Testing exception"),
HttpStatus.NOT_FOUND);
return responseEntity;
}
}
初始化类
package ...;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
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.bind.annotation.ExceptionHandler;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
@Configuration
@ComponentScan("...")
@EnableWebMvc
@EnableTransactionManagement
@PropertySource("classpath:application.properties")
public class WebAppConfig extends WebMvcConfigurerAdapter {
@ExceptionHandler({ Exception.class })
public ResponseEntity<RestClientException> handle(NoHandlerFoundException e) {
return new ResponseEntity<>(new RestClientException("Testing exception"), HttpStatus.NOT_FOUND);
}
...
@Override
public void addViewControllers(ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/404.jsp").setViewName("404");
}
}
还有一个初始化器
类(公共类初始化器实现WebApplication初始化器),它似乎与一些建议的选项(在这里和这里定义)相冲突;因此webapp-init类没有被修改。
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="ROOT" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<error-page>
<error-code>404</error-code>
<location>/error</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error</location>
</error-page>
</web-app>
放置404.jsp
或404.html
文件(当前在以下所有位置用于测试目的):
src/main/resources
├── ...
├── error
│ └── 404.html
├── public
│ ├── 404.html
│ └── error
│ └── 404.html
├── templates
│ └── 404.html
└── ...
src/main/webapp/WEB-INF/
├── error.jsp
├── tags
│ └── ...
└── views
├── 404.html
├── 404.jsp
├── error.jsp
└── ...
你知道有什么遗漏或错误吗?
确保您可以访问404页面,然后添加这些代码。
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NoHandlerFoundException.class)
public String handle404(Model model, HttpServletRequest req, Exception ex) {
return "/404";
}
}
应用亚马尔
spring:
mvc:
throwExceptionIfNoHandlerFound: true # if page not found, it will throw error, and then ControllerAdvice will catch the error.
PS: springBoot version=2.4.2;Java=15
阅读Spring Boot文档,这对我很有用:
@Bean
public ErrorPageRegistrar errorPageRegistrar() {
return registry -> registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/index.html")); }
这相当于web.xml.
虽然不像我想的那么清楚,但这是一种工作版本,至少可以为错误页面提供一些定制。这是第一种方法,但希望能帮助其他人。
已处理异常的列表并不广泛,但主要是处理404个错误(NoHandlerFoundException
)和其他典型错误,如InternalServerErrorException
和NullPointerException
,试图在最后用一个通用错误捕获所有其他属于异常的错误。
请注意,这不包括与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 {
public CustomSimpleMappingExceptionResolver() {
// Turn logging on by default
setWarnLogCategory(getClass().getName());
}
@Override
public String buildLogMessage(Exception e, HttpServletRequest req) {
return "MVC exception: " + e.getLocalizedMessage();
}
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
// Log exception
ex.printStackTrace();
String exceptionCause = ex.toString();
String exceptionType = ex.getClass().getCanonicalName();
// Get the ModelAndView to use
ModelAndView mav = super.doResolveException(request, response, handler, ex);
// Make more information available to the view - note that SimpleMappingExceptionResolver adds the exception already
mav.addObject("url", request.getRequestURL());
mav.addObject("timestamp", new Date());
ArrayList<String> exceptions404 = new ArrayList<String>(
Arrays.asList(
NoHandlerFoundException.class.getName()
)
);
ArrayList<String> exceptions500 = new ArrayList<String>(
Arrays.asList(
InternalServerErrorException.class.getName(),
NullPointerException.class.getName()
)
);
String userExceptionDetail = ex.toString();
String errorHuman = "";
String errorTech = "";
if (exceptions404.contains(exceptionType)) {
errorHuman = "We cannot find the page you are looking for";
errorTech = "Page not found";
userExceptionDetail = String.format("The page %s cannot be found", request.getRequestURL());
mav.setViewName("/error/404");
mav.addObject("status", HttpStatus.NOT_FOUND.value());
} else if (exceptions500.contains(exceptionType)) {
errorHuman = "We cannot currently serve the page you request";
errorTech = "Internal error";
userExceptionDetail = "The current page refuses to load due to an internal error";
mav.setViewName("/error/500");
mav.addObject("status", HttpStatus.INTERNAL_SERVER_ERROR.value());
} else {
errorHuman = "We cannot serve the current page";
errorTech = "General error";
userExceptionDetail = "A generic error prevents from serving the page";
mav.setViewName("/error/generic");
mav.addObject("status", response.getStatus());
}
Exception userException = new Exception(userExceptionDetail);
mav.addObject("error_human", errorHuman);
mav.addObject("error_tech", errorTech);
mav.addObject("exception", userException);
return mav;
}
}
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 {
@Resource
private Environment env;
// ...
@Bean
HandlerExceptionResolver customExceptionResolver () {
CustomSimpleMappingExceptionResolver resolver = new CustomSimpleMappingExceptionResolver();
Properties mappings = new Properties();
// Mapping Spring internal error NoHandlerFoundException to a view name
mappings.setProperty(NoHandlerFoundException.class.getName(), "/error/404");
mappings.setProperty(InternalServerErrorException.class.getName(), "/error/500");
mappings.setProperty(NullPointerException.class.getName(), "/error/500");
mappings.setProperty(ClassNotFoundException.class.getName(), "/error/500");
mappings.setProperty(Exception.class.getName(), "/error/generic");
resolver.setExceptionMappings(mappings);
// Set specific HTTP codes
resolver.addStatusCode("404", HttpStatus.NOT_FOUND.value());
resolver.addStatusCode("500", HttpStatus.INTERNAL_SERVER_ERROR.value());
resolver.setDefaultErrorView("/error/generic");
resolver.setDefaultStatusCode(200);
// This resolver will be processed before the default ones
resolver.setOrder(Ordered.HIGHEST_PRECEDENCE);
resolver.setExceptionAttribute("exception");
return resolver;
}
// ...
@Bean
public InternalResourceViewResolver setupViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
super.addViewControllers(registry);
}
}
初始化器。java(添加
dispatcherServlet.setThroweExceptionIfNoHandlerFound(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 {
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(WebAppConfig.class);
servletContext.addListener(new ContextLoaderListener(ctx));
ctx.setServletContext(servletContext);
DispatcherServlet dispatcherServlet = new DispatcherServlet(ctx);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
// Add the dispatcher servlet mapping manually and make it initialize automatically
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", dispatcherServlet);
servlet.addMapping("/");
servlet.addMapping("*.png");
servlet.addMapping("*.jpg");
servlet.addMapping("*.css");
servlet.addMapping("*.js");
servlet.addMapping("*.txt");
servlet.setLoadOnStartup(1);
// ...
}
}
与错误类相关的视图和标记的结构:
src/main/webapp/WEB-INF/
├── tags
│ └── error.tag
└── views
├── error
│ ├── 404.jsp
│ ├── 500.jsp
└────── generic.jsp
SRC/main/webapp/WEB-INF/tags/error.tag
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<head>
<title>Error page</title>
</head>
<body>
<div class="container">
<h3><c:out value="${error_human}" /></h3>
<p><br/><br/></p>
<div class="panel panel-primary">
<div class="panel-heading">
<c:out value="${error_tech}" />
</div>
<div class="panel-body">
<p><c:out value="${exception_message}" /></p>
</div>
</div>
</div>
</body>
</html>
src/main/webapp/WEB-INF/views/error/404。jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
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"
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"
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 />
问题内容: 如你所知,在XML中,配置方式如下: 但是我还没有找到在Java配置中做到这一点的方法。我尝试的第一种方法是: 它似乎有效,但是在检索资源方面存在冲突。 有办法吗? 问题答案: 在Spring Framework中,有许多处理异常(尤其是404错误)的方法. 首先,你仍然可以在web.xml中使用标签,并自定义错误页面。这是一个例子。 其次,可以r对所有控制器使用一个,如下所示: 为此
我是spring+MVC的新手。我找到了一个脚本,我可以运行这个脚本的一部分。这个脚本配置spring mvc没有xml,在Java方面.我将所有的jar放入web-inf/lib。 控制器配置.Java WebAppInitializer.java HomeController.java FilmController.java film.java 我有两个问题: 如果我写“http://loca
您可以帮助进行spring集成配置吗。 收到消息后,我收到: 我的代码: 我有类似的JmsInboudGateway配置,用于其他没有.requestChannel和.replyChannel的队列。 如果不是注入请求通道bean,而是用文本名称声明它,得到了这个 以及更多的文字宣传问题。
我是Spring MVC的新手,正在尝试在Spring MVC中创建我的第一个项目。请帮助我解决以下错误:- 控制台中出现以下错误:- web.xml dispatcher-servlet.xml 控制器类别 索引1.jsp Eclipse项目层次结构
我正在尝试spring-mvc和JSON。 项目在tomcat中部署成功,如localhost:8080/manager 所示 我试图发送json数据,并遵循“http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/” 我缺少什么? 谢谢
我已经编写了一个Spring MVC应用程序,它显示了在XML视图中运行的测试用例和套件的报告。我已经编写了模型类,它很好,我已经编写了以下文件,但我想处理程序映射有一些问题 我的Controller.java类如下所示 我得到一个404错误,控制台显示错误为 在名为“MVC-Dispatcher”的DispatcherServlet中,未找到URI为[/springmvc/suite/suite