关于SpringMVC的异常中心DefaultExceptionHandler
2017-03-26 16:43
190 查看
摘要: 在服务端经常会遇到需要手动的抛出异常,比如业务系统,校验异常,比较通用的处理方案是在最顶层进行拦截异常,例如Struts的全局异常处理,而Spring的异常处理机制就相对于Struts来说好用多了
在服务端经常会遇到需要手动的抛出异常,比如业务系统,校验异常,比较通用的处理方案是在最顶层进行拦截异常,例如Struts的全局异常处理,而Spring的异常处理机制就相对于Struts来说好用多了。
第一种:配置式
第二种:注解式
然后在后端采用@ControllerAdvice注解进行全局处理。
在DefaultExceptionHandler中使用了BeanValidators,代码如下。
Message对象:
在服务端经常会遇到需要手动的抛出异常,比如业务系统,校验异常,比较通用的处理方案是在最顶层进行拦截异常,例如Struts的全局异常处理,而Spring的异常处理机制就相对于Struts来说好用多了。
第一种:配置式
<!-- 基于配置文件式的异常处理 --> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthorizedException">error/403</prop> <prop key="com.sirdc.modules.exceptions.ServiceException">error/503</prop> </props> </property> </bean>
第二种:注解式
<!-- 基于注解式子的异常处理 --> <bean id="exceptionHandlerExceptionResolver" class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"></bean>
然后在后端采用@ControllerAdvice注解进行全局处理。
import com.sirdc.modules.exceptions.ServiceException; import com.sirdc.modules.validator.BeanValidators; import com.sirdc.modules.web.model.Message; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.servlet.ModelAndView; import javax.validation.ConstraintViolationException; import java.util.List; /** * 自定义统一异常处理中心 * * @version Revision: 0.0.1 * @author: weihuang.peng * @Date: 2015年1月17日 */ @ControllerAdvice public class DefaultExceptionHandler { /** * 处理业务异常 * * @param request * @param model * @param exception * @return Model */ @ExceptionHandler({ServiceException.class}) public ModelAndView processServiceException(NativeWebRequest request, ServiceException exception) { ModelAndView model = new ModelAndView("/error/503"); model.addObject("exception", exception); model.addObject("message", "服务器未能处理您的请求"); return model; } /** * 处理校验异常 * * @param request * @param exception * @return */ @ExceptionHandler({ConstraintViolationException.class}) @ResponseBody public Message processConstraintViolationException(NativeWebRequest request, ConstraintViolationException exception) { exception.printStackTrace(); List<String> list = BeanValidators.extractPropertyAndMessageAsList(exception, ": "); list.add(0, "数据验证失败:"); return handleMessage(list.toArray(new String[]{})); } @ExceptionHandler({Exception.class}) public ModelAndView processException(NativeWebRequest request, Exception exception) { exception.printStackTrace(); ModelAndView model = new ModelAndView("/error/500"); model.addObject("exception", exception); model.addObject("message", "服务器出错了"); return model; } /** * 添加Flash消息 * * @param messages 消息 * @return */ protected Message handleMessage(String... messages) { Message model = new Message(); StringBuilder sb = new StringBuilder(); for (String message : messages) { sb.append(message).append(messages.length > 1 ? "<br/>" : ""); } model.setCode("500"); model.setMessage(sb.toString()); return model; } }
在DefaultExceptionHandler中使用了BeanValidators,代码如下。
import java.util.List; import java.util.Map; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.Validator; import com.google.common.collect.Lists; import com.google.common.collect.Maps; /** * <pre> * JSR303 Validator(Hibernate Validator)工具类. * JSR 303 – Bean Validation 是一个数据验证的规范. * * validate(Object)的返回值是Set,每一个ConstraintViolation包含了出错的 * message和propertyPath、InvalidValue, 不同场景有不同的显示需求,国际化在propertyPath的i18N翻译上. * ConstraintViolation中包含propertyPath, message 和invalidValue等信息. * 提供了各种convert方法,适合不同的i18n需求: * 1. List<String>, String内容为message * 2. List<String>, String内容为propertyPath + separator + message * 3. Map<propertyPath, message> * * 详情见wiki: http://hibernate.org/subprojects/validator/docs/ * </pre> * * @author HaiYan */ @SuppressWarnings({ "unchecked", "rawtypes" }) public class BeanValidators { /** * 调用JSR303的validate方法, 验证失败时抛出ConstraintViolationException, * 而不是返回constraintViolations. */ public static void validateWithException(Validator validator, Object object, Class<?>... groups) throws ConstraintViolationException { Set constraintViolations = validator.validate(object, groups); if (!constraintViolations.isEmpty()) { throw new ConstraintViolationException(constraintViolations); } } /** * 转换ConstraintViolationException中的Set<ConstraintViolations>中为List<message>. * * @param e * ConstraintViolationException * @return List<String>, String内容为message */ public static List<String> extractMessage(ConstraintViolationException e) { return extractMessage(e.getConstraintViolations()); } /** * 转换Set<ConstraintViolation>为List<message>. * * @param constraintViolations * @return List<String>, String内容为message */ public static List<String> extractMessage( Set<? extends ConstraintViolation> constraintViolations) { List<String> errorMessages = Lists.newArrayList(); for (ConstraintViolation violation : constraintViolations) { errorMessages.add(violation.getMessage()); } return errorMessages; } /** * 转换ConstraintViolationException中的Set<ConstraintViolations>为Map<property, * message>. * * @param e * ConstraintViolationException * @return Map<String, String> key=propertyPath,value=message */ public static Map<String, String> extractPropertyAndMessage( ConstraintViolationException e) { return extractPropertyAndMessage(e.getConstraintViolations()); } /** * 转换Set<ConstraintViolation>为Map<property, message>. * * @param e * ConstraintViolationException * @return Map<String, String> key=propertyPath,value=message */ public static Map<String, String> extractPropertyAndMessage( Set<? extends ConstraintViolation> constraintViolations) { Map<String, String> errorMessages = Maps.newHashMap(); for (ConstraintViolation violation : constraintViolations) { errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage()); } return errorMessages; } /** * 转换ConstraintViolationException中的Set<ConstraintViolations>为List< * propertyPath message>. * * @param e * ConstraintViolationException * @return List<String>, String内容为propertyPath + separator + message */ public static List<String> extractPropertyAndMessageAsList( ConstraintViolationException e) { return extractPropertyAndMessageAsList(e.getConstraintViolations(), " "); } /** * 转换ConstraintViolationException的Set<ConstraintViolations>为List< * propertyPath + separator + message>. * * @param e * ConstraintViolationException * @param separator * 分隔符 * @return List<String>, String内容为propertyPath + separator + message */ public static List<String> extractPropertyAndMessageAsList( ConstraintViolationException e, String separator) { return extractPropertyAndMessageAsList(e.getConstraintViolations(), separator); } /** * 转换Set<ConstraintViolations>为List<propertyPath message>. * * @param constraintViolations * @return List<String>, String内容为propertyPath + separator + message */ public static List<String> extractPropertyAndMessageAsList( Set<? extends ConstraintViolation> constraintViolations) { return extractPropertyAndMessageAsList(constraintViolations, " "); } /** * 转换Set<ConstraintViolation>为List<propertyPath + separator + message>. * * @param e * ConstraintViolationException * @return List<String>, String内容为propertyPath + separator + message */ public static List<String> extractPropertyAndMessageAsList( Set<? extends ConstraintViolation> constraintViolations, String separator) { List<String> errorMessages = Lists.newArrayList(); for (ConstraintViolation violation : constraintViolations) { errorMessages.add(violation.getPropertyPath() + separator + violation.getMessage()); } return errorMessages; } }
Message对象:
import java.io.Serializable; /** * * @author: weihuang.peng * @version Revision: 0.0.1 * @Date: 2015年1月21日 */ public class Message implements Serializable { private static final long serialVersionUID = 1769341992221383236L; private String code; private String message; private Object data; /** * @author: weihuang.peng * @return the data */ public Object getData() { return data; } /** * @author: weihuang.peng * @param data the data to set */ public void setData(Object data) { this.data = data; } /** * @return the code */ public String getCode() { return code; } /** * @param code the code to set */ public void setCode(String code) { this.code = code; } /** * @return the message */ public String getMessage() { return message; } /** * @param message the message to set */ public void setMessage(String message) { this.message = message; } }
相关文章推荐
- 关于springMVC转换json出现的异常
- 关于springmvc报的空指针的异常,就是在这个service方法报空指针的原因
- 关于springMVC转换json出现的异常
- 关于web.xml配置error-page或者springmvc添加自定义异常返回画面,画面没有显示
- springmvc中关于cacheManager的异常
- SpringMVC传参,接参,集中传参,jsp页面提参的方式,以及关于SpringMVC下载和异常方式
- 关于合理使用SpringMVC统一异常处理机制以改善代码风格的一些思考
- 关于合理使用SpringMVC统一异常处理机制以改善代码风格的一些思考
- 关于springMVC 接收date 类型为空时候的异常解决办法
- 关于SpringMVC的几种异常配置
- SpringMVC利用注解实现异常处理
- 关于MYSQL数据库Timestamp类型为空抛异常问题的处理
- javaweb异常提示信息统一处理(使用springmvc,附源码)
- 关于Struts + Hibernate 的项目产生的“非常异常”
- SpringMVC学习--异常处理器
- SpringMVC统一异常处理简单配置
- 关于Response.redirect和Response.End出现线程中止异常的处理
- 关于Use of @OneToMany or @ManyToMany targeting an unmapped class: com.xxx.domain异常
- SpringMVC统一异常处理机制
- springMVC高级部分(数据校验,数据错误回显(自定义格式错误显示),拦截器,异常处理,文件上传,文件下载,springmvc运行流程以及springmvc和struts2对比)