1. 背景
小黄:
不同的 Controller 发生不同的异常, 我想要做不同的动作, 能不能简单配置优雅的实现?
比如
com.feilong.psi.controller.channel.ChannelController
如果出现com.feilong.psi.exception.SignNotEqualsException
那么跳转到404 页面 如果出现com.feilong.psi.exception.TradeStatusCanNotPayException
那么跳转到 首页
2. 实现
good question, 一看小黄就是个有追求的孩子, let's go~~
我们先来看如何实现,再来看原理
第1步 , 项目依赖 feilong spring
项目 pom.xml 添加 feilong spring 依赖
注: feilong spring 4.0.3 ,need spring 4 version
<project>
....
<properties>
<version.feilong-spring>4.0.3</version.feilong-spring>
....
</properties>
....
<repositories>
<repository>
<id>feilong-repository</id>
<url>https://raw.github.com/venusdrogon/feilong-platform/repository</url>
</repository>
</repositories>
....
<dependencies>
....
<dependency>
<groupId>com.feilong.platform.spring</groupId>
<artifactId>feilong-spring-all</artifactId>
<version>${version.feilong-spring}</version>
</dependency>
....
</dependencies>
....
第2步 使用 com.feilong.spring.web.servlet.handler.SimpleMappingHandlerMethodExceptionResolver
新建个 springmvc-pay-channel-exception.xml
文件
...
<!-- 通道异常解决器 -->
<bean id="channelExceptionResolver" class="com.feilong.spring.web.servlet.handler.SimpleMappingHandlerMethodExceptionResolver">
<property name="order" value="1" />
<property name="preventResponseCaching" value="true" />
<property name="mappedHandlerClasses">
<array>
<value>com.feilong.psi.controller.channel.ChannelController</value>
</array>
</property>
<property name="exceptionMappings">
<props>
<!-- 安全签名参数不正确的异常. -->
<prop key="com.feilong.psi.exception.SignNotEqualsException">redirect:/errors/404</prop>
<!-- 交易的状态不能去支付的异常.
since 20180920 change from 500 to /
-->
<prop key="com.feilong.psi.exception.TradeStatusCanNotPayException">redirect:/</prop>
</props>
</property>
</bean>
...
第3步 加载上面配置的 channelExceptionResolver
springmvc-exceptionResolver.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<import resource="classpath:springmvc/pay/springmvc-pay-channel-exception.xml" />
<import resource="classpath:springmvc/pay/springmvc-pay-redirect-exception.xml" />
<import resource="classpath:springmvc/pay/springmvc-pay-notify-exception.xml" />
<!-- exceptionResolver -->
<bean id="exceptionResolver" class="com.baozun.exception.ExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="com.baozun.exception.BusinessException">forward:/errors/error</prop>
<prop key="java.lang.Throwable">forward:/errors/error</prop>
</props>
</property>
</bean>
</beans>
注意 要保证公司全局的 com.baozun.exception.ExceptionResolver
在最下面
3. 原理
feilong com.feilong.spring.web.servlet.handler.SimpleMappingHandlerMethodExceptionResolver
借鉴于 SimpleMappingExceptionResolver
, 并在此基础上进行了扩展 ,参见扩展5
4. 扩展- 使用自定义 view
小李:
我看到在上面的 xml 中可以直接配置 redirect:/errors/404 就跳转到404 页面, 我现在有个支付通知controller , 如果业务正常处理, 响应支付网关 Continnue 字符串, 如果有异常 我要返回 stop 字符串, 这个 stop 我想在 xml 中配置 该如何实现呢?
good question
你可以使用feilong spring 自定义的 printwrite view
springmvc-viewResolver-printwrite.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<bean class="com.feilong.spring.web.servlet.view.printwriter.PrintWriterViewResolver">
<property name="order" value="-1" />
<property name="prefix" value="printwrite:" />
</bean>
</beans>
springmvc-pay-notify-exception.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- doku notify异常解决器 -->
<bean id="dokuNotifyExceptionResolver" class="com.feilong.spring.web.servlet.handler.SimpleMappingHandlerMethodExceptionResolver">
<property name="order" value="1" />
<property name="preventResponseCaching" value="true" />
<property name="mappedHandlerClasses">
<array>
<value>com.feilong.psi.doku.controller.notify.DokuNotifyController</value>
</array>
</property>
<property name="exceptionMappings">
<props>
<!-- STOP -->
<prop key="com.feilong.psi.exception.PsiNotifyException">printwrite:STOP</prop>
<prop key="java.lang.Throwable">printwrite:STOP</prop>
</props>
</property>
</bean>
</beans>
5. 扩展- 使用自定义 exceptionAndExceptionViewNameBuilderMap
在实际的业务场景中, 简单的 properties 结构的 exceptionMappings
可能不能满足业务需求
比如,跳转的url 地址需要使用部分参数
此时你使用 exceptionAndExceptionViewNameBuilderMap
属性, 配置成如下格式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- Doku Redirect 异常解决器 -->
<bean id="redirectExceptionResolver" class="com.feilong.spring.web.servlet.handler.SimpleMappingHandlerMethodExceptionResolver">
<property name="order" value="1" />
<property name="preventResponseCaching" value="true" />
<property name="mappedHandlerClasses">
<array>
<value>com.feilong.psi.doku.controller.redirect.DokuRedirectController</value>
</array>
</property>
<property name="exceptionAndExceptionViewNameBuilderMap">
<map>
<entry key="com.feilong.psi.exception.PayResultStatusNotPaidException" value-ref="payResultStatusNotPaidExceptionViewNameBuilder"/>
</map>
</property>
</bean>
<bean id="payResultStatusNotPaidExceptionViewNameBuilder" class="com.baozun.store.web.controller.payment.builder.PayResultStatusNotPaidExceptionViewNameBuilder"/>
</beans>
关于 PayResultStatusNotPaidExceptionViewNameBuilder
public class PayResultStatusNotPaidExceptionViewNameBuilder extends AbstractExceptionViewNameBuilder{
@Override
public String build(HandlerMethod handlerMethod,Exception exception,HttpServletRequest request,HttpServletResponse response){
PayResultStatusNotPaidException notPaidException = (PayResultStatusNotPaidException) exception;
return buildViewName(request,notPaidException);
}
private String buildViewName(HttpServletRequest request,PayResultStatusNotPaidException notPaidException){
String tradeNo = notPaidException.getTradeNo();
String s = PaymentSecureBuilder.buildS(getMemberId(request).toString(), S_NAME_RESULT, tradeNo);
return "redirect:" + SECURE_PAYMENT_FAIL_URL + "?transactionId=" + tradeNo + "&s=" + s;
}
...
}
注意 : 优先级 exceptionAndExceptionViewNameBuilderMap
> exceptionMappings
属性
相关推荐
springmvc异常处理的博文如下: http://blog.csdn.net/dlf123321/article/details/50756003
异常一层一层的向上抛出,但是开发人员肯定不想要用户看到代码出错,因此需要将异常屏蔽了,SpringMVC提供了异常处理的手段。
Maven+SpringMVC实现统一异常处理
本文档主要介绍了SpringMVC的ModelAndView机制,使用SpringMVC实现文件上传,下载以及全局异常处理机制
SpringMVC中异常处理机制,简单案例,里面有详细说明以及博客说明。
springmvc返回json的全局异常统一处理demo,有问题可以留言。
12SpringMVC异常处理.md
Springmvc请求处理方法参数Springmvc请求处理方法参数
SpringMVC通过HandlerExceptionResolver接口来处理程序的异常,包括Handler映射、数据绑定和目标方法执行时发生的异常。 主要测试HandlerExceptionResolver的具体实现类的具体用法
SSM笔记-SpringMVC的异常处理,包含了ExceptionHandler注解、ResponseStatusExceptionResolver、DefaultHandlerExceptionResolver、SimpleMappingExceptionResolver的使用和试验
springmvc跨域处理,和过滤器方式跨域处理的主要代码,整体系统基于springboot框架搭建
主要介绍了springmvc如何进行异常处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
使用Spring+SpringMVC+hibernate做的一个小项目,附带数据库
springMVC3学习(八)--全局的异常处理(源码) 文章地址:http://blog.csdn.net/itmyhome1990/article/details/26286435
本视频针对博客内容,讲解springMVC框架中的统一异常处理的知识点和实例,以及500错误和404错误异常处理上的区别,简单易懂,言简意赅。
通过aop拦截获取json请求数据,对数据进行处理判断,如果不合法则抛出异常,配置全局异常处理类,在异常处理类中直接将处理结果返回调用处,减少每次在方法中解析json数据然后在判断,减少代码冗余
SpringMVC入门很简单之异常处理,具体参考博文:http://www.cnblogs.com/liukemng/tag/SpringMVC/
SpringMVC处理全局异常在使用Shiro权限控制框架后,如果使用注解在Controller控制访问的角色,如果权限不足,就会抛出Authorization
springmvc+spring线程池处理http并发请求数据同步控制问题