统⼀异常处理@ExceptionHandler
⼀、如何设置全局的异常处理
⽤@RequestBody,@ResponBody,不费吹灰之⼒就解决了JSon⾃动绑定。
接着就发现,如果遇到RuntimeException,需要给出⼀个默认返回JSON,有以下三种⽅式:
1.当这个Controller中任何⼀个⽅法发⽣异常,⼀定会被这个⽅法拦截到。然后,输出⽇志。封装Map并返回,页⾯上得到status为fal。代码如下:
1 @Controller
2public class AccessController {
3
4/**
5 * 异常页⾯控制
6 *
7 * @param runtimeException
8 * @return脑瘤能活多久
9*/
10 @ExceptionHandler(RuntimeException.class)
11public @ResponBody
12 Map<String,Object> runtimeExceptionHandler(RuntimeException runtimeException) {
13 (LocalizedMessage());
苦糖果14
15 Map model = new TreeMap();
16 model.put("status", fal);
17return model;
18 }
19
20 }
2.返回到错误界⾯
爱真的很简单
代码如下:
1 @Controller
2public class AccessController {
3/**
4 * 异常页⾯控制
5 *
6 * @param runtimeException
7 * @return
8*/
9 @ExceptionHandler(RuntimeException.class)
盘存表
10public String runtimeExceptionHandler(RuntimeException runtimeException,
11 ModelMap modelMap) {
12 (LocalizedMessage());
13
14 modelMap.put("status", IntegralConstant.FAIL_STATUS);
15return "exception";
16 }
17 }
3.使⽤ @ControllerAdvice,不⽤任何的配置,只要把这个类放在项⽬中,Spring能扫描到的地⽅。就可以实现全局异常的回调。
代码如下:
@ControllerAdvice
public class SpringExceptionHandler{
/**
* 全局处理Exception
* 错误的情况下返回500
* @param ex
epson打印机使用方法* @param req
* @return
*/
天龙功放官网
@ExceptionHandler(value = {Exception.class })
public ResponEntity<Object> handleOtherExceptions(final Exception ex, final WebRequest req) {
TResult tResult = new TResult();
tResult.tStatus(CodeType.V_500);
tResult.Message());
return new ResponEntity<Object>(tResult,HttpStatus.OK);
}
}
⼆、@ExceptionHandler注解
直接在Controller ⾥⾯加上⽤@ExceptionHandler 标注⼀个处理异常的⽅法像下⾯这样⼦这样,Controller ⾥⾯的⽅法抛出了MissingServletRequestParameterException 异常就会执⾏上⾯的这个⽅
法来进⾏异常处理。
如下⾯的代码:如果我没有传⼊id 值,那么就会抛出MissingServletRequestParameterException 的异常,就会被上⾯的异常处理⽅法处理。
上⾯的@ExceptionHandler(MissingServletRequestParameterException.class)这个注解的value 的值是⼀个Class[]类型的,这⾥的ExceptionClass 是你⾃⼰指定的,你也可以指定多个需要处理的异常类型,⽐如这样@ExceptionHandler(value =
{MissingServletRequestParameterException.class,BindException.class}),这样就会处理多个异常了。
但这个只会是在当前的Controller ⾥⾯起作⽤,如果想在所有的Controller ⾥⾯统⼀处理异常的话,可以⽤@ControllerAdvice 来创建⼀个专门处理的类。如⼀中的3所述。
三、@ControllerAdvice 注解
@ControllerAdvice ,是Spring3.2提供的新注解,从名字上可以看出⼤体意思是控制器增强。让我们先看看@ControllerAdvice 的实现:没什么特别之处,该注解使⽤@Component 注解,这样的话当我们使⽤<context:component-scan>扫描时也能扫描到。
再⼀起看看官⽅提供的comment 。
⼤致意思是:
@ExceptionHandler(MissingServletRequestParameterException .class )@ResponStatus(HttpStatus .BAD _REQUEST)public void processMethod(MissingServletRequestParameterException ex,HttpServletRequest request ,HttpServletRespon respon) throws IOExceptio
System .out.println ("抛异常了!"+ex .getLocalizedMessage ()); logger .error ("抛异常了!"+ex .getLocalizedMessage ()); respon .getWriter ().printf (ex .getMessage ()); respon .flushBuffer ();}1
2
3
4
5
6
7
8@RequestMapping ("/index")public String index(@MyUr Ur ur,@RequestParam String id,ModelMap modelMap){ return "login";}
1
2
3
知了怎么叫4
@ControllerAdvice 是⼀个@Component ,⽤于定义@ExceptionHandler ,@InitBinder 和@ModelAttribute ⽅法,适⽤于所有使⽤@RequestMapping ⽅法。
Spring4之前,@ControllerAdvice 在同⼀调度的Servlet 中协助所有控制器。Spring4已经改变:@ControllerAdvice ⽀持配置控制器的⼦集,⽽默认的⾏为仍然可以利⽤。
在Spring4中, @ControllerAdvice 通过annotations(), baPackageClass(), baPackages() ⽅法定制⽤于选择控制器⼦集。不过据经验之谈,只有配合@ExceptionHandler 最有⽤,其它两个不常⽤。
库房管理制度在我们提到,如果单使⽤@ExceptionHandler ,只能在当前Controller 中处理异常。但当配合@ControllerAdvice ⼀起使⽤的时候,就可以摆脱那个限制了。如果我们想定义⼀个处理全局的异常
乍⼀眼看上去毫⽆问题,但这⾥有⼀个纰漏,由于Exception 是异常的⽗类,如果你的项⽬中出现过在⾃定义异常中使⽤@ResponStatus 的情况,你的初衷是碰到那个⾃定义异常响应对应的状态码,⽽这个控制器增强处理类,会⾸先进⼊,并直接返回,不会再有
@ResponStatus 的事情了,这⾥为了解决这种纰漏,我提供了⼀种解决⽅式。
如果碰到了某个⾃定义异常加上了@ResponStatus ,就继续抛出,这样就不会让⾃定义异常失去加上@ResponStatus 的初衷。@Controller @RequestMapping (value = "exception")public class ExceptionHandlerController { @RequestMapping (value = "e2/{id}", method = { RequestMethod.GET }) @ResponBody public String testExceptionHandle2(@PathVariable(value = "id") Integer id) { List<String> list = Arrays.asList(new String[]{"a","b","c","d"}); return (id-1); }}
1
2
3
4
5
6
7
8
9
10
11
12