https://howtodoinjava.com/spring-mvc/spring-mvc-simplemappingexceptionresolver-example/

在某些编码错误的应用程序中,当发生未知异常时,应用程序服务器通常会在网页本身中向用户显示恶意异常堆栈跟踪。 在这种情况下,用户与此堆栈跟踪无关,并抱怨您的应用程序对用户不友好。 此外,当您向用户公开内部方法调用层次结构时,它还可能证明存在潜在的安全风险。 尽管可以将 Web 应用程序的web.xml配置为在发生 HTTP 错误或类异常的情况下显示友好的 JSP 页面,但是 Spring MVC 支持一种更强大的方法来管理类异常的视图。

HandlerExceptionResolverSimpleMappingExceptionResolver

在 Spring MVC 应用程序中,可以在 Web 应用程序上下文中注册一个或多个异常解析器 bean,以解析未捕获的异常。 这些 Bean 必须实现DispatcherServletHandlerExceptionResolver接口才能自动检测它们。 Spring MVC 附带了一个简单的异常解析器,即SimpleMappingExceptionResolver,用于以可配置的方式将每个类别的异常映射到一个视图。

假设我们有一个异常类,即AuthException。 而且,我们希望每次将此异常从任何地方抛出到应用程序中时,我们都希望显示一个预定的视图页面/WEB-INF/views/error/authExceptionView.jsp。 这样配置就可以了。

SimpleMappingExceptionResolver配置

  1. <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  2. <property name="exceptionMappings">
  3. <props>
  4. <prop key="com.howtodoinjava.demo.exception.AuthException">
  5. error/authExceptionView
  6. </prop>
  7. </props>
  8. </property>
  9. <property name="defaultErrorView" value="error/genericView"/>
  10. </bean>

完整的上下文配置为:

applicationContext.xml

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  3. xsi:schemaLocation="http://www.springframework.org/schema/beans
  4. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  5. http://www.springframework.org/schema/context/
  6. http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  7. <context:component-scan base-package="com.howtodoinjava.demo" />
  8. <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
  9. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
  10. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  11. <property name="prefix" value="/WEB-INF/views/" />
  12. <property name="suffix" value=".jsp" />
  13. </bean>
  14. <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
  15. <property name="basename" value="messages" />
  16. </bean>
  17. <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  18. <property name="exceptionMappings">
  19. <props>
  20. <prop key="com.howtodoinjava.demo.exception.AuthException">
  21. error/authExceptionView
  22. </prop>
  23. </props>
  24. </property>
  25. <property name="defaultErrorView" value="error/genericView"/>
  26. </bean>
  27. </beans>

请注意最后的defaultErrorView属性。 如果 spring 上下文检测到未从应用程序抛出的任何异常,但未在exceptionMappings属性列表中列出,则它将呈现视图/WEB-INF/views/error/genericView.jsp

测试SimpleMappingExceptionResolver配置的应用程序

为了测试目的,让我们创建AuthException.java

AuthException.java

  1. package com.howtodoinjava.demo.exception;
  2. import java.util.Date;
  3. public class AuthException extends RuntimeException
  4. {
  5. private static final long serialVersionUID = 1L;
  6. private Date date;
  7. private String message;
  8. public AuthException(Date date, String message) {
  9. super();
  10. this.date = date;
  11. this.message = message;
  12. }
  13. public Date getDate() {
  14. return date;
  15. }
  16. public String getMessage() {
  17. return message;
  18. }
  19. @Override
  20. public String toString() {
  21. return "AuthException [date=" + date + ", message=" + message + "]";
  22. }
  23. }

并从任何控制器抛出此异常。

EmployeeController.java

  1. @Controller
  2. @RequestMapping("/employee-module")
  3. public class EmployeeController
  4. {
  5. @RequestMapping(value="/getAllEmployees", method = RequestMethod.GET)
  6. public String welcome(Model model)
  7. {
  8. throw new AuthException(new Date(), "Something bad happened dude !! Run Away :-(");
  9. }
  10. }

并在路径/WEB-INF/views/error/中创建两个 jsp 文件

authExceptionView.jsp

  1. <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
  3. <html>
  4. <head>
  5. <title>Authentication Exception</title>
  6. </head>
  7. <body>
  8. <h2>Exception occured at: </h2><fmt:formatDate value="${exception.date}" pattern="yyyy-MM-dd" />
  9. <h2>Exception Message : </h2>${exception.message}
  10. </body>
  11. </html>

genericView.jsp

  1. <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
  2. <html>
  3. <head>
  4. <title>Generic Exception</title>
  5. </head>
  6. <body>
  7. <h2>Some generic error message</h2>
  8. </body>
  9. </html>

现在点击 URL:http://localhost:8080/springmvcexample/employee-module/getAllEmployees

Spring MVC `SimpleMappingExceptionResolver`示例 - 图1

SimpleMappingExceptionResolver示例

现在从控制器抛出任何其他异常,例如NullPointerException,如下所示。

  1. @Controller
  2. @RequestMapping("/employee-module")
  3. public class EmployeeController
  4. {
  5. @RequestMapping(value="/getAllEmployees", method = RequestMethod.GET)
  6. public String welcome(Model model)
  7. {
  8. throw new NullPointerException();
  9. }
  10. }

然后再次点击以下网址:http://localhost:8080/springmvcexample/employee-module/getAllEmployees

Spring MVC `SimpleMappingExceptionResolver`示例 - 图2

SimpleMappingExceptionResolver 通用错误示例

显然,应用程序现在可以在出现异常的情况下找到正确的视图。 前视图中没有更多错误堆栈跟踪。

学习愉快!