@ExceptionHandler 控制层异常统一拦截
在编写程序时,可以通过try-catch进行捕获,捕获那些被检查的异常类型,如果不进行处理,是无法编译的。但是除了被检查异常外还有运行时异常,运行时异常是无法确定的,可能在程序的任何地方抛出。如何去捕获运行时异常,使程序在抛出运行时异常时不崩溃呢?可以看下try-catch的原理,其实,try-catch的实现,是通过给方法注册一个ExceptionHandler,当异常抛出时,会在堆栈最顶部的调用方法中寻找合适的ExceptionHandler,使用try-catch,相当于注册了一个ExceptionHandler进行异常处理
用@RequestBody,@ResponseBody,不费吹灰之力就解决了JSon自动绑定。接着就发现,如果遇到RuntimeException,需要给出一个默认返回JSON
三种方式:
1.当这个Controller中任何一个方法发生异常,一定会被这个方法拦截到。然后,输出日志。封装Map并返回,页面上得到status为false。就这么简单。
代码如下
1 @Controller
2 public class AccessController {
3
4 /**
5 * 异常页面控制
6 *
7 * @param runtimeException
8 * @return
9 */
10 @ExceptionHandler(RuntimeException.class)
11 public @ResponseBody
12 Map<String,Object> runtimeExceptionHandler(RuntimeException runtimeException) {
13 logger.error(runtimeException.getLocalizedMessage());
14
15 Map model = new TreeMap();
16 model.put("status", false);
17 return model;
18 }
19
20 }
2.返回到错误界面
代码如下
1 @Controller
2 public class AccessController {
3 /**
4 * 异常页面控制
5 *
6 * @param runtimeException
7 * @return
8 */
9 @ExceptionHandler(RuntimeException.class)
10 public String runtimeExceptionHandler(RuntimeException runtimeException,
11 ModelMap modelMap) {
12 logger.error(runtimeException.getLocalizedMessage());
13
14 modelMap.put("status", IntegralConstant.FAIL_STATUS);
15 return "exception";
16 }
17 }
3.使用 @ControllerAdvice,不用任何的配置,只要把这个类放在项目中,Spring能扫描到的地方。就可以实现全局异常的回调。
代码如下
@ControllerAdvice
public class SpringExceptionHandler{
/**
* 全局处理Exception
* 错误的情况下返回500
* @param ex
* @param req
* @return
*/
@ExceptionHandler(value = {Exception.class})
public ResponseEntity<Object> handleOtherExceptions(final Exception ex, final WebRequest req) {
TResult tResult = new TResult();
tResult.setStatus(CodeType.V_500);
tResult.setErrorMessage(ex.getMessage());
return new ResponseEntity<Object>(tResult,HttpStatus.OK);
}
}
通过这样一个被@ExceptionHandler注解修饰的方法,就能捕获controller层所有抛出的InsertMessageException类型异常,并对异常进行相应的处理,或者在basecontroller里包装一个handleException方法,就能捕捉所有controller抛出的异常并进行处理:代码如下
@ResponseBody
@ExceptionHandler
public String handleException(Exception ex) {
if(null != ex.getStackTrace() && ex.getStackTrace().length > 1) {
log.error("系统异常:", ex);
}
ex.printStackTrace();
if (MissingServletRequestParameterException.class.equals(ex.getClass())) {
String message = ex.getMessage();
int index1 = message.indexOf("'");
int index2 = message.lastIndexOf("'");
//return encodeResult(RESULT_CODE_BAD_REQUEST, "请求参数错误", null);
return encodeResult(RESULT_CODE_BAD_REQUEST, "请求参数"+message.substring(index1+1,index2)+"未提供", null);
} else if(java.sql.SQLSyntaxErrorException.class.equals(ex.getClass())) {
return encodeResult(RESULT_CODE_BAD_REQUEST, "数据出错,请稍后重试", null);
} else if(org.springframework.jdbc.BadSqlGrammarException.class.equals(ex.getClass())) {
return encodeResult(RESULT_CODE_BAD_REQUEST, "数据访问异常,请稍后重试", null);
}else {
if(StringUtils.isNotBlank(ex.getMessage()) && !ex.getMessage().matches(".*(Exception|Error).*")) {
return encodeError(ex);
}
return encodeError("哎呀!服务器打了会小盹,请稍后再试!");
}
}