首先提倡下Hibernate的验证器,功能强大且使用方面,Hibernate Validator提供包括国际化,传统的字符空,非法的输入等,而且给了很友善的message信息。
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>. */ public static List<String> extractMessage(ConstraintViolationException e) { return extractMessage(e.getConstraintViolations()); } /** * 辅助方法, 转换Set<ConstraintViolation>为List<message> */ public static List<String> extractMessage(Set<? extends ConstraintViolation> constraintViolations) { List<String> errorMessages = new ArrayList<String>(); for (ConstraintViolation violation : constraintViolations) { errorMessages.add(violation.getMessage()); } return errorMessages; } /** * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为Map<property, message>. */ public static Map<String, String> extractPropertyAndMessage(ConstraintViolationException e) { return extractPropertyAndMessage(e.getConstraintViolations()); } /** * 辅助方法, 转换Set<ConstraintViolation>为Map<property, message>. */ public static Map<String, String> extractPropertyAndMessage(Set<? extends ConstraintViolation> constraintViolations) { Map<String, String> errorMessages = new HashMap<String, String>(); for (ConstraintViolation violation : constraintViolations) { errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage()); } return errorMessages; } /** * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath message>. */ public static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e) { return extractPropertyAndMessageAsList(e.getConstraintViolations(), " "); } /** * 辅助方法, 转换Set<ConstraintViolations>为List<propertyPath message>. */ public static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations) { return extractPropertyAndMessageAsList(constraintViolations, " "); } /** * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath + separator + message>. */ public static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e, String separator) { return extractPropertyAndMessageAsList(e.getConstraintViolations(), separator); } /** * 辅助方法, 转换Set<ConstraintViolation>为List<propertyPath + separator + message>. */ public static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations, String separator) { List<String> errorMessages = new ArrayList<String>(); for (ConstraintViolation violation : constraintViolations) { errorMessages.add(violation.getPropertyPath() + separator + violation.getMessage()); } return errorMessages; } }
结合HibernateValidator,添加自定义的exception
?
public class CustormizeException extends RuntimeException { private static final long serialVersionUID = -3703423976960486177L; private int errorCode; public CustormizeException(ResultCode statusCode) { this(statusCode, null); } public CustormizeException(ResultCode resultCode, String message) { super(resultCode.name() + (message == null ? "" : " " + message)); this.errorCode = resultCode.code(); } public String toString() { return String.format("{\"errorCode\":\"%s\",\"errorMsg\":\"%s\"}", errorCode, this.getMessage()); } public int getErrorCode() { return errorCode; } public boolean checkStatus(ResultCode resultCode) { return errorCode == resultCode.code(); } }
?增加异常处理的切面处理器,能够很快的捕获信息,反馈给各个终端设备,而不至于抛出恶心的代码异常信息。
@ControllerAdvice public class CustormizeExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler(value = {CustormizeException.class}) public final ResponseEntity<?> handleException(CustormizeException exception, WebRequest request) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("text/plain; charset=UTF-8")); return handleExceptionInternal(exception, exception.getCode() + ":" + exception.getMessage(), headers, exception.status, request); } @ExceptionHandler(value = {ConstraintViolationException.class}) public final ResponseEntity<?> handleException(ConstraintViolationException exception, WebRequest request) { Map<String, String> errors = BeanValidators.extractPropertyAndMessage(exception.getConstraintViolations()); String errorBody = JSON.toJSONString(errors, true); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("text/plain; charset=UTF-8")); return handleExceptionInternal(exception, errorBody, headers, HttpStatus.BAD_REQUEST, request); } }
?总结:
异常处理其实不会让你头疼,但是我们常常忽略把异常丢给用户,这种事情成妾做不到,只能通过切面的方式在方法后捕获,然后进行反馈。
原文:http://cywhoyi.iteye.com/blog/2247602