做电子签章登录哪个网站,PHP是做网站最好的,建网站 服务器,服务器怎么装网站吗异常处理 1.认识异常处理1.1 异常处理的必要性1.2 异常的分类1.3 如何处理异常1.3.1 捕获异常1.3.2 抛出异常1.3.4 自定义异常 1.4 Spring Boot 默认的异常处理 2.使用控制器通知3.自定义错误处理控制器3.1 自定义一个错误的处理控制器3.2 自定义业务异常类3.2.1 自定义异常类3… 异常处理 1.认识异常处理1.1 异常处理的必要性1.2 异常的分类1.3 如何处理异常1.3.1 捕获异常1.3.2 抛出异常1.3.4 自定义异常 1.4 Spring Boot 默认的异常处理 2.使用控制器通知3.自定义错误处理控制器3.1 自定义一个错误的处理控制器3.2 自定义业务异常类3.2.1 自定义异常类3.2.2 自定义全局捕获异常3.2.3 测试自定义异常类 1.认识异常处理
异常处理 是编程语言的机制用来处理软件系统中出现的异常情况增强代码的可读性。
1.1 异常处理的必要性
异常处理用于解决一些程序无法掌控但又必须面对的情况。例如程序需要读取文件、连接网络、使用数据库等但可能文件不存在、网络不畅通、数据库无效等情况。为了程序能继续运行此时就需要把这些情况进行异常处理。异常处理的方法通常有以下几种
将异常通知给开发人员、运维人员或用户。使因为异常中断的程序以适当的方式继续运行或者退出。保存用户的当前操作或者进行数据回滚。释放资源。
1.2 异常的分类
Error代表编译和系统的错误不允许捕获。Exception标准 Java 库的方法所激发的异常包含运行异常 Runtime_Exception 和非运行异常 Non_RuntimeException 的子类。Runtime Exception运行时异常。Non RuntimeException非运行时可检测的异常Java 编译器利用分析方法或构造方法中可能产生的结果来检测程序中是否含有检测异常的处理程序每个可能的可检测异常、方法或构造方法的 throws 子句必须列出该异常对应的类。Throw用户自定义异常。
1.3 如何处理异常
1.3.1 捕获异常
捕获异常的格式见以下代码
try{//......
}
catch(//......
)
finally{//......
}try在 try 语句中编写可能发生异常的代码即正常的业务功能代码。如果执行完 try 语句不发生异常则执行 finally 语句如果有的话和 finally 后面的代码如果发生异常则尝试去匹配 catch 语句。catch捕捉错误并处理。finallyfinally 语句是可选的无论异常是否发生、是否匹配、是否被处理finally 都会执行。
一个 try 至少要有一个 catch 语句或至少要有 1 1 1 个 finally 语句。finally 不是用来处理异常的也不会捕获异常是为了做一些清理工作如流的关闭、数据库连接的关闭等。
1.3.2 抛出异常
除用 try 语句处理异常外还可以用 throw、throws 抛出异常。
执行 throw 语句的地方是一个异常抛出点后面必须是一个异常对象且必须写在函数中。
throw、throws 的用法见以下代码。
throw 语法
throw(异常对象);throws 语法
[(修饰符)](返回值类型)(方法名)([参数列表])[throws(异常类)]{...}1.3.4 自定义异常
在应用程序的开发过程中经常会自定义异常类以避免使用 try 产生重复代码。自定义异常类一般是通过扩展 Exception 类来实现的。这样的自定义异常属于 检查异常checked exception。如果要自定义非检查异常则需要继承 RuntimeException。
1.4 Spring Boot 默认的异常处理
Spring Boot 提供了一个默认处理异常的映射。在 Spring Boot 的 Web 项目中尝试访问一个不存在的 URLhttp://localhost:8080/pipi会得到 Spring Boot 中内置的异常处理如下提示
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat May 18 22:49:20 CST 2019
There was an unexpected error (typeNot Found, status404).
No message available.同样的地址如果发送的请求带有 Content-Type→application/json;charsetUTF-8 则返回的是 JSON 格式的错误结果见以下输出结果
{timestamp:2019-05-18T14:47:46.7220000,status: 404,error: Not Found,message: No message available,path: /pipi
}从上面结果可以看出Spring Boot 会根据消费者发送的 Content-Type 来返回相应的异常内容如果 Content-Type 是 applicaton/json则返回 JSON 文件如果 Content-Type是 text/html则返回 HTML 文件。
2.使用控制器通知
在编写代码时需要对异常进行处理。进行异常处理的普通的代码是 try...catch 结构。但在开发业务时只想关注业务正常的代码对于 catch 语句中的捕获异常希望交给异常捕获来处理不单独在每个方法中编写。这样不仅可以减少冗余代码还可以减少因忘记写 catch 而出现错误的概率。
Spring 正好提供了一个非常方便的异常处理方案控制器通知ControllerAdvice 或 RestcontrollerAdvice它将所有控制器作为一个切面利用切面技术来实现。
通过基于 ControllerAdvice 或 RestControllerAdvice 的注解可以对异常进行全局统一处理默认对所有的 Controller 有效。如果要限定生效范围则可以使用 ControllerAdvice 支持的限定范围方式。
按注解ControllerAdvice(annotationsRestController.class)。按包名ControllerAdvice(org.example.controller)。按类型ControllerAdvice(assignableTypes{Controllerlnterface.class, AbstractController.class})。
这是 ControllerAdvice 进行统一异常处理的优点它能够细粒度地控制该异常处理器针对哪些 Controller、包或类型有效。
可以利用这一特性在一个系统实现多个异常处理器然后 Controller 可以有选择地决定使用哪个使得异常处理更加灵活、降低侵入性。
异常处理类会包含以下一个或多个方法
InitBinder对表单数据进行绑定用于定义控制器参数绑定规则。如转换规则、格式化等。可以通过这个注解的方法得到 WebDataBinder 对象它在参数转换之前被执行。ModelAttribute在控制器方法被执行前对所有 Controller 的 Model 添加属性进行操作。ExceptionHandler定义控制器发生异常后的操作可以拦载所有控制器发生的异常。ControllerAdvice统一异常处理通过 ExceptionHandler(valueException.class) 来指定捕获的异常。ControllerAdvice ExceptionHandle 可以处理除 404 以外的运行异常。
3.自定义错误处理控制器
3.1 自定义一个错误的处理控制器
以下代码演示如何自定义一个错误的处理控制器。
package com.example.demo.Controller;import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;RestController
/*springboot提供了默认的错误映射地址error
RequestMapping(${server.error.path:${error.path:/error}})
RequestMapping(/error)
上面2种写法都可以
*/
RequestMapping(/error)
//继承springboot提供的ErrorController
public class TestErrorController implements ErrorController {//一定要重写方法,默认返回null就可以,不然报错,因为getErrorPath为空Overridepublic String getErrorPath() {return null;}//一定要添加url映射,指向errorRequestMappingpublic MapString, Object handleError() {//用Map容器返回信息MapString, Object map new HashMapString, Object();map.put(code, 404);map.put(msg, 不存在);return map;}/*这里加一个能正常访问的页面,作为比较因为写在一个控制器所以它的访问路径是http://localhost:8080/error/ok*/RequestMapping(/ok)ResponseBodypublic MapString, Object noError() {//用Map容器返回信息MapString, Object map new HashMapString, Object();map.put(code , 200);map.put(msg, 正常这是测试页面);return map;}
}启动项目访问一个不存在的网址则返回下方信息 访问正确定义的映射则返回下方正确信息 3.2 自定义业务异常类
3.2.1 自定义异常类
自定义异常类需要继承 Exception异常类。这里继承 RuntimeException代码如下
package com.example.demo.exception;public class BusinessException extends RuntimeException{//自定义错误码private Integer code;//自定义构造器必须输入错误码及内容public BusinessException(int code, String msg) {super(msg);this.code code;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code code;}
}RuntimeException 和 Error 是非检查异常其他的都是检查异常。所有方法都可以在不声明 throws 方法的情况下抛出 RuntimeException 及其子类不可以在不声明的情况下抛出非 RuntimeException即非 RuntimeException 要自己写 catch 语句处理如果 RuntimeException 不使用 try...catch 进行捕捉则会导致程序运行中断。
3.2.2 自定义全局捕获异常
package com.example.demo.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;ControllerAdvice
public class CustomerBusinessExceptionHandler {ResponseBodyExceptionHandler(BusinessException.class)public MapString, Object businessExceptionHandler(BusinessException e) {MapString, Object map new HashMapString, Object();map.put(code, e.getCode());map.put(message, e.getMessage());//发生异常进行日志记录此处省略return map;}
}3.2.3 测试自定义异常类
创建控制器。以抛出 BusinessException 的自定义异常。
package com.example.demo.controller;import com.example.demo.exception.BusinessException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;RestController
public class TestController {RequestMapping(/BusinessException)public String testResponseStatusExceptionResolver(RequestParam(i) int i) {if (i 0) {throw new BusinessException(600, 自定义业务错误);}return success;}}启动项目访问 http://localhost:8080/BusinessException?i0 测试异常处理情况则抛出下方错误信息