尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Spring Boot异常处理

Spring Boot异常处理 一、前言Spring Boot对异常的处理有一套默认的机制当应用中产生异常时Spring Boot根据发送请求头中的accept是否包含text/html来分别返回不同的响应信息。当从浏览器地址栏中访问应用接口时请求头中的accept便会包含text/html信息产生异常时Spring Boot通过org.springframework.web.servlet.ModelAndView对象来装载异常信息并以HTML的格式返回而当从客户端访问应用接口产生异常时客户端访问时请求头中的accept不包含text/htmlSpring Boot则以JSON的格式返回异常信息。下面来验证一下。二、默认异常处理机制假设应用中有如下一个ControllerRestControllerRequestMapping(calculate)publicclassCalculateController{GetMapping(/{divisor:\\d}/{dividend:\\d})publicvoidcalculate(PathVariableLongdivisor,PathVariableLongdividend){thrownewRuntimeException(calculate is error);}}在代码中我们主动的抛出了一个RuntimeException使用浏览器访问http://localhost:8080/calculate/1/0可看到页面返回了一些异常描述并且请求头的accpet包含了text/html片段。接着使用模拟发送REST请求,使用IDEA插件HTTP Client发送http://localhost:8080/calculate/1/0可以看到请求头的accept值为*/*并且返回一段JSON格式的信息。查看Spring Boot的BasicErrorController类便可看到这一默认机制的具体实现可看到errorHtml和error方法的请求地址和方法是一样的唯一的区别就是errorHtml通过produces {“text/html”}判断请求头的accpet属性中是否包含text/html如果包含便走该方法。三、自定义html异常页面我们可以通过在src/main/resources/resources/error路径下定义友好的异常页面比如定义一个500.html页面!DOCTYPEhtmlhtmllangenheadmetacharsetUTF-8title500/title/headbody系统内部异常/body/html使用浏览器再次访问http://localhost:8080/calculate/1/0同样的我们也可以定义404.html等常见的HTTP状态码对应的异常页面。!DOCTYPEhtmlhtmllangenheadmetacharsetUTF-8title404/title/headbody链接走丢了/body/html使用浏览器访问http://localhost:8080/calculater/1/0通过自定义html异常页面并不会影响客户端发送请求异常返回的结果。四、自定义异常处理除了可以通过自定义html异常页面来改变浏览器访问接口时产生的异常信息我们也可以自定义异常处理来改表默认的客户端访问接口产生的异常信息。我们手动定义一个CalculateErrorException继承RuntimeException。publicclassCalculateErrorExceptionextendsRuntimeException{privatestaticfinallongserialVersionUID-1L;privateStringid;publicCalculateErrorException(Stringid){super(calculate is error);this.idid;}publicStringgetId(){returnid;}publicvoidsetId(Stringid){this.idid;}}然后定义一个Controller异常处理类ControllerExceptionHandlerControllerAdvicepublicclassControllerExceptionHandler{ExceptionHandler(CalculateErrorException.class)ResponseBodyResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)publicMapString,ObjecthandleUserNotExistsException(CalculateErrorExceptione){MapString,ObjectmapnewHashMap();map.put(id,e.getId());map.put(message,e.getMessage());returnmap;}}其中注解ExceptionHandler指定了要处理的异常类型注解ResponseStatus指定异常处理方法返回的HTTP状态码为HttpStatus.INTERNAL_SERVER_ERROR即500。HttpStatus是一个spring自带的枚举类型封装了常见的HTTP状态码及描述publicenumHttpStatus{CONTINUE(100,Continue),SWITCHING_PROTOCOLS(101,Switching Protocols),PROCESSING(102,Processing),CHECKPOINT(103,Checkpoint),OK(200,OK),CREATED(201,Created),ACCEPTED(202,Accepted),NON_AUTHORITATIVE_INFORMATION(203,Non-Authoritative Information),NO_CONTENT(204,No Content),RESET_CONTENT(205,Reset Content),PARTIAL_CONTENT(206,Partial Content),MULTI_STATUS(207,Multi-Status),ALREADY_REPORTED(208,Already Reported),IM_USED(226,IM Used),MULTIPLE_CHOICES(300,Multiple Choices),MOVED_PERMANENTLY(301,Moved Permanently),FOUND(302,Found),/** deprecated */DeprecatedMOVED_TEMPORARILY(302,Moved Temporarily),SEE_OTHER(303,See Other),NOT_MODIFIED(304,Not Modified),/** deprecated */DeprecatedUSE_PROXY(305,Use Proxy),TEMPORARY_REDIRECT(307,Temporary Redirect),PERMANENT_REDIRECT(308,Permanent Redirect),BAD_REQUEST(400,Bad Request),UNAUTHORIZED(401,Unauthorized),PAYMENT_REQUIRED(402,Payment Required),FORBIDDEN(403,Forbidden),NOT_FOUND(404,Not Found),METHOD_NOT_ALLOWED(405,Method Not Allowed),NOT_ACCEPTABLE(406,Not Acceptable),PROXY_AUTHENTICATION_REQUIRED(407,Proxy Authentication Required),REQUEST_TIMEOUT(408,Request Timeout),CONFLICT(409,Conflict),GONE(410,Gone),LENGTH_REQUIRED(411,Length Required),PRECONDITION_FAILED(412,Precondition Failed),PAYLOAD_TOO_LARGE(413,Payload Too Large),/** deprecated */DeprecatedREQUEST_ENTITY_TOO_LARGE(413,Request Entity Too Large),URI_TOO_LONG(414,URI Too Long),/** deprecated */DeprecatedREQUEST_URI_TOO_LONG(414,Request-URI Too Long),UNSUPPORTED_MEDIA_TYPE(415,Unsupported Media Type),REQUESTED_RANGE_NOT_SATISFIABLE(416,Requested range not satisfiable),EXPECTATION_FAILED(417,Expectation Failed),I_AM_A_TEAPOT(418,Im a teapot),/** deprecated */DeprecatedINSUFFICIENT_SPACE_ON_RESOURCE(419,Insufficient Space On Resource),/** deprecated */DeprecatedMETHOD_FAILURE(420,Method Failure),/** deprecated */DeprecatedDESTINATION_LOCKED(421,Destination Locked),UNPROCESSABLE_ENTITY(422,Unprocessable Entity),LOCKED(423,Locked),FAILED_DEPENDENCY(424,Failed Dependency),UPGRADE_REQUIRED(426,Upgrade Required),PRECONDITION_REQUIRED(428,Precondition Required),TOO_MANY_REQUESTS(429,Too Many Requests),REQUEST_HEADER_FIELDS_TOO_LARGE(431,Request Header Fields Too Large),UNAVAILABLE_FOR_LEGAL_REASONS(451,Unavailable For Legal Reasons),INTERNAL_SERVER_ERROR(500,Internal Server Error),NOT_IMPLEMENTED(501,Not Implemented),BAD_GATEWAY(502,Bad Gateway),SERVICE_UNAVAILABLE(503,Service Unavailable),GATEWAY_TIMEOUT(504,Gateway Timeout),HTTP_VERSION_NOT_SUPPORTED(505,HTTP Version not supported),VARIANT_ALSO_NEGOTIATES(506,Variant Also Negotiates),INSUFFICIENT_STORAGE(507,Insufficient Storage),LOOP_DETECTED(508,Loop Detected),BANDWIDTH_LIMIT_EXCEEDED(509,Bandwidth Limit Exceeded),NOT_EXTENDED(510,Not Extended),NETWORK_AUTHENTICATION_REQUIRED(511,Network Authentication Required);...}编写完自定义异常处理逻辑后我们将CalculateController中的方法抛出的异常改为CalculateErrorExceptionGetMapping(/{divisor:\\d}/{dividend:\\d})publicvoidcalculate(PathVariableLongdivisor,PathVariableLongdividend){thrownewCalculateErrorException(500);}重启项目再次访问http://localhost:8080/calculater/1/0响应如下
返回列表