出现异常后,跳转指定的页面
不配置spirng-MVC.xml
Controller
方式1;
//处理异常,注意入参中,不能有Model,Map等,如果需要给requestion添加对象,使用ModelAndView @ExceptionHandler({ArithmeticException.class}) public ModelAndView ArithmeticException(Exception ex){ ModelAndView modelAndView = new ModelAndView("error"); modelAndView.addObject("ex",ex); return modelAndView; } @RequestMapping(value = "/testexception",method = RequestMethod.GET) public String testexception(){ int a = 1/0; return "login"; }
方式2:
我们重新创建一个类(类名无关),将上面处理异常的方法放进去;
@ControllerAdvice public class HandleException { @ExceptionHandler({ArithmeticException.class}) //捕获指定的异常 public ModelAndView ArithmeticException(Exception ex){ ModelAndView modelAndView = new ModelAndView("error"); modelAndView.addObject("ex",ex); return modelAndView; } }
配置spirng-MVC.xml
controller不需要在写异常处理的方法了。
<!--key:需要些错误的全限定路径--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!--配置异常的名字--> <property name="exceptionAttribute" value="ex"></property> <property name="exceptionMappings"> <props> <prop key="java.lang.ArithmeticException">error</prop> </props> </property> </bean>
@ResponseStatus注解
1、如果这个注解放在的方法上:直接放回一个错误页面
@ResponseStatus(reason = "测试",value = HttpStatus.NOT_FOUND) @RequestMapping(value = "/testexception",method = RequestMethod.GET) public String testexception(){ return "login"; }
1、注解类
定义一个错误的类
@ResponseStatus(reason = "错误消息",value = HttpStatus.BAD_REQUEST) public class MyException extends Exception{ public MyException(){ super(); } public MyException(String message){ super(message); } }
controller
@RequestMapping(value = "/testexception",method = RequestMethod.GET) public String testexception() throws MyException { if (true){ MyException myException = new MyException(); throw myException; } return "login"; }
编写统一处理异常类
可预知异常处理(由程序员自己抛出的异常)
1、编写一个错误类继承RunTimeException,不继承Exception的原因是,在代码中手动抛出RunTimeException异常,在代码中不需要进行try...cache等
public class CustomException extends RuntimeException { //错误代码信息(自己定义) ResultCode resultCode; public CustomException(ResultCode resultCode){ this.resultCode = resultCode; } public ResultCode getResultCode(){ return resultCode; } }
2、service层抛出异常
if(cmsPage1!=null){ //页面已经存在 //抛出异常,异常内容就是页面已经存在 throw new CustomException(CmsCode.CMS_ADDPAGE_EXISTSNAME); }
3、编写捕获异常类
@ControllerAdvice//控制器增强 public class ExceptionCatch { private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class); //捕获CustomException此类异常 @ResponseBody //返回给前端json数据 @ExceptionHandler(CustomException.class) //捕获相应的错误类 public ResponseResult customException(CustomException customException){ //记录日志 LOGGER.error("catch exception:{}",customException.getMessage()); //获取错误码(自定义的) ResultCode resultCode = customException.getResultCode(); return new ResponseResult(resultCode); } }
4、springboot配置(由于我们的捕获类写在了common模块中,所以spring boot启动的时候,需要扫描这个模块)
@SpringBootApplication @EntityScan("com.xuecheng.framework.domain.cms")//扫描实体类 @ComponentScan(basePackages={"com.xuecheng.framework"}) //扫描common模块 public class ManageCmsApplication { public static void main(String[] args) { SpringApplication.run(ManageCmsApplication.class,args); } }
不可预知异常处理(由框架自己抛出)
1、对捕获异常类进行扩展
总结:捕获Exception异常(所有的异常),如果该异常在map中有对应的错误码(我们提前将可能出现的异常用map存储起来),返回该错误码
@ControllerAdvice//控制器增强 public class ExceptionCatch { private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class); //定义map,配置异常类型所对应的错误代码 private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS; //定义map的builder对象,去构建ImmutableMap(ImmutableMap的使用需要定义builder对象,如果使用其他HashMap就不需要了) protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableMap.builder(); //提前将系统可能抛出的异常代码添加相应的错误代码块 static { //定义异常类型所对应的错误代码(注意此时ImmutableMap还没有数据,需要等待build()) builder.put(HttpMessageNotReadableException.class,CommonCode.INVALID_PARAM); } //捕获CustomException此类异常 @ResponseBody @ExceptionHandler(CustomException.class) public ResponseResult customException(CustomException customException){ //记录日志 LOGGER.error("catch exception:{}",customException.getMessage()); ResultCode resultCode = customException.getResultCode(); return new ResponseResult(resultCode); } //捕获其他框架抛出的异常 @ResponseBody @ExceptionHandler(Exception.class) public ResponseResult exception(Exception exception){ //记录日志 LOGGER.error("catch exception:{}",exception.getMessage()); if(EXCEPTIONS == null){ //此时,ImmutableMap构建成功,ImmutableMap有了数据,且ImmutableMap不能在被修改了(只读) EXCEPTIONS = builder.build(); //我们可以直接put完数据之后,直接执行build() } //从EXCEPTIONS中找异常类型所对应的错误代码,如果找到了将错误代码响应给用户,如果找不到给用户响应99999异常 ResultCode resultCode = EXCEPTIONS.get(exception.getClass()); if(resultCode !=null){ return new ResponseResult(resultCode); }else{ //返回99999异常 return new ResponseResult(CommonCode.SERVER_ERROR); } } }