现在的位置: 首页 > 操作系统 > 正文

SpringMVC错误页面配置

2020年02月13日 操作系统 ⁄ 共 6002字 ⁄ 字号 评论关闭

当前SpringMVC非常流行,在大多数情况,我们都需要自定义一些错误页面(例如:401, 402, 403, 500…),以便更友好的提示。对于spring mvc,这些当然是支持自定义的,spring是怎么做的? 还是去看看spring的源码吧:

原理

DispatcherServlet

众所周知,springmvc的入口是DispatcherServlet, 在DispatcherServlet的源码中,不知你是否注意到了以下方法:

protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // Check registered HandlerExceptionResolvers... ModelAndView exMv = null; for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) { exMv = handlerExceptionResolver.resolveException(request, response, handler, ex); if (exMv != null) { break; } } if (exMv != null) { if (exMv.isEmpty()) { request.setAttribute(EXCEPTION_ATTRIBUTE, ex); return null; } // We might still need view name translation for a plain error model... if (!exMv.hasView()) { exMv.setViewName(getDefaultViewName(request)); } if (logger.isDebugEnabled()) { logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv, ex); } WebUtils.exposeErrorRequestAttributes(request, ex, getServletName()); return exMv; } throw ex;}

这个方法就是springmvc对于异常的处理,其调用了HandlerExceptionResolver的resolveException方法。HandlerExceptionResolver有众多实现类,其中,重点看看SimpleMappingExceptionResolver(我们就是要通过它来配置自定义错误页面)。

SimpleMappingExceptionResolver

public class SimpleMappingExceptionResolver extends AbstractHandlerExceptionResolver { ... private Properties exceptionMappings; private Class<?>[] excludedExceptions; private Map<String, Integer> statusCodes = new HashMap<String, Integer>(); ... public void setExceptionMappings(Properties mappings) { this.exceptionMappings = mappings; } public void setStatusCodes(Properties statusCodes) { for (Enumeration<?> enumeration = statusCodes.propertyNames(); enumeration.hasMoreElements();) { String viewName = (String) enumeration.nextElement(); Integer statusCode = new Integer(statusCodes.getProperty(viewName)); this.statusCodes.put(viewName, statusCode); } }}@Overrideprotected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // Expose ModelAndView for chosen error view. String viewName = determineViewName(ex, request); if (viewName != null) { // Apply HTTP status code for error views, if specified. // Only apply it if we're processing a top-level request. Integer statusCode = determineStatusCode(request, viewName); if (statusCode != null) { applyStatusCodeIfPossible(request, response, statusCode); } return getModelAndView(viewName, ex, request); } else { return null; }}protected String determineViewName(Exception ex, HttpServletRequest request) { String viewName = null; if (this.excludedExceptions != null) { for (Class<?> excludedEx : this.excludedExceptions) { if (excludedEx.equals(ex.getClass())) { return null; } } } // Check for specific exception mappings. if (this.exceptionMappings != null) { viewName = findMatchingViewName(this.exceptionMappings, ex); } // Return default error view else, if defined. if (viewName == null && this.defaultErrorView != null) { if (logger.isDebugEnabled()) { logger.debug("Resolving to default view '" + this.defaultErrorView + "' for exception of type [" + ex.getClass().getName() + "]"); } viewName = this.defaultErrorView; } return viewName;}protected String findMatchingViewName(Properties exceptionMappings, Exception ex) { String viewName = null; String dominantMapping = null; int deepest = Integer.MAX_VALUE; for (Enumeration<?> names = exceptionMappings.propertyNames(); names.hasMoreElements();) { String exceptionMapping = (String) names.nextElement(); int depth = getDepth(exceptionMapping, ex); if (depth >= 0 && (depth < deepest || (depth == deepest && dominantMapping != null && exceptionMapping.length() > dominantMapping.length()))) { deepest = depth; dominantMapping = exceptionMapping; viewName = exceptionMappings.getProperty(exceptionMapping); } } if (viewName != null && logger.isDebugEnabled()) { logger.debug("Resolving to view '" + viewName + "' for exception of type [" + ex.getClass().getName() + "], based on exception mapping [" + dominantMapping + "]"); } return viewName;}protected Integer determineStatusCode(HttpServletRequest request, String viewName) { if (this.statusCodes.containsKey(viewName)) { return this.statusCodes.get(viewName); } return this.defaultStatusCode;}

由此可见:

SimpleMappingExceptionResolver通过 exceptionMappings和statusCodes来确立Exception、http状态码以及view之间的映射关系。明白这个就很简单了,我们可以通过设置exceptionMappings、statusCodes的值来实现我们自定义的映射关系。

实战

页面准备

    我们在WEB-INF/views/commons/error(目录自己定)新建我们自定义的错误页面,404.html, 500.html等等。

    SimpleMappingExceptionResolver只实现映射关系,我们还需要通过配置web.xml来实现。

    <error-page> <error-code>404</error-code> <location>/error/404.html</location></error-page><error-page> <error-code>500</error-code> <location>/error/500.html</location></error-page>

    在spring-mvc配置文件中将404.html、500.html等设置为资源文件,避免被springmvc再次拦截。

    <mvc:resources mapping="/error/**" location="/WEB-INF/views/commons/error/" />

    配置SimpleMappingExceptionResolver。

    <bean class="org.springframework.web.servlet.handler. SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <map> <entry key="ResourceNotFoundException" value="common/error/resourceNotFoundError" /> <entry key=".DataAccessException" value="common/error/dataAccessError" /> </map> </property> <property name="statusCodes"> <map> <entry key="common/error/resourceNotFoundError" value="404" /> <entry key="common/error/dataAccessError" value="500" /> </map> </property></bean>

到此,就实现我们需要的配置了。

SpringMVC+MyBatis集成配置 http://www.xuebuyuan.com/Linux/2016-09/135212.htm

SpringMVC总结篇 http://www.xuebuyuan.com/Linux/2016-06/132659.htm

Spring+SpringMVC企业快速开发架构搭建 http://www.xuebuyuan.com/Linux/2015-09/122942.htm

SpringMVC的乱码处理 http://www.xuebuyuan.com/Linux/2015-07/120542.htm

Spring MVC+Spring3+Hibernate4开发环境搭建 http://www.xuebuyuan.com/Linux/2013-07/87119.htm

Spring MVC整合Freemarker基于注解方式 http://www.xuebuyuan.com/Linux/2013-02/79660.htm

基于注解的Spring MVC简单介绍 http://www.xuebuyuan.com/Linux/2012-02/54896.htm

SpringMVC详细示例实战教程 http://www.xuebuyuan.com/Linux/2015-06/118461.htm

Spring MVC 框架搭建及详解 http://www.xuebuyuan.com/Linux/2012-01/52740.htm

SpringMVC 异常处理 http://www.xuebuyuan.com/Linux/2015-06/119049.htm

SpringMVC框架入门配置 IDEA下搭建Maven项目 http://www.xuebuyuan.com/Linux/2016-09/134918.htm

本文永久更新链接地址:http://www.xuebuyuan.com/Linux/2016-12/138097.htm

以上就上有关SpringMVC错误页面配置的相关介绍,要了解更多SpringMVC错误页面,SpringMVC,SpringMVC错误页面配置,编程,Linux编程,Linux Shell,Android,Android教程,JAVA,C语言,Python,HTML5内容请登录学步园。

抱歉!评论已关闭.