Spring Security技术栈开发企业级认证与授权(四)RESTful API服务异常处理
2018-04-01 15:14
513 查看
当我们从浏览器访问不存在的
一、Spring Boot的默认处理方式分析
从浏览器端访问
启动
从
从
对比上面的两种访问方式,返回的错误类型是不一样的,浏览器访问返回的是一个
这段源代码来自于
第一个方法和第二个方法处理的都是同一个
以上的例子都是访问资源不存在的案例,访问的处理逻辑并未进入对应的
从浏览器端访问
而从客户端访问,返回的依然是
二、自定义服务异常处理
在实际的开发过程中,如果出现
浏览器端自定义处理方式
这里仅仅介绍一种最简单的方式来处理异常,在
自定义服务异常处理类
在实际的开发中,我们完全可以自定义服务异常处理类,以满足实际的开发需求。这里写一个异常类,在业务逻辑处理中,可以根据需要手动抛出自己自定义的异常。比如:
为了测试,在
当访问这个
有时候我们前端不需要这么多的信息,只需要部分信息,这个时候就需要自定义异常处理了,而不是采用
当一个类加上了
这就是我们自定义的异常处理后的数据了。
Spring Security技术栈开发企业级认证与授权系列文章列表:
Spring Security技术栈开发企业级认证与授权(一)环境搭建
Spring Security技术栈开发企业级认证与授权(二)使用Spring MVC开发RESTful API
Spring Security技术栈开发企业级认证与授权(三)表单校验以及自定义校验注解开发
Spring Security技术栈开发企业级认证与授权(四)RESTful API服务异常处理
Spring Security技术栈开发企业级认证与授权系列文章列表:
Spring Security技术栈开发企业级认证与授权(一)环境搭建
Spring Security技术栈开发企业级认证与授权(二)使用Spring MVC开发RESTful API
Spring Security技术栈开发企业级认证与授权(三)表单校验以及自定义校验注解开发
Spring Security技术栈开发企业级认证与授权(四)RESTful API服务异常处理
Spring Security技术栈开发企业级认证与授权(五)使用Filter、Interceptor和AOP拦截REST服务
Spring Security技术栈开发企业级认证与授权(六)使用REST方式处理文件服务
Spring Security技术栈开发企业级认证与授权(七)使用Swagger自动生成API文档
示例代码下载地址:
项目已经上传到码云,欢迎下载,内容所在文件夹为
Spring Boot的
RESTful API的时候,往往会返回
Spring Boot内置的
404错误界面,但是作为前后端分离的应用,相同的
API也许会在其他终端访问,比如手机
APP等,那么也会是相同的处理方式吗?
一、Spring Boot的默认处理方式分析
从浏览器端访问
启动
Spring Boot项目,从浏览器访问一个不存在的
API,如“
/user/hello”,这时候返回来的是一个
HTML页面,如下图所示:
从
APP端访问
从
APP端访问我们可以使用模拟
RESTful API发送器来进行发送,我这里使用的
Paw软件,你可以在你的谷歌浏览器上安装
Postman来进行发送。访问“
/user/hello”返回的结果如下如所示:
对比上面的两种访问方式,返回的错误类型是不一样的,浏览器访问返回的是一个
HTML页面,而客户端访问返回的是一个
JSON数据。那么问题来了,
Spring Boot是如何确定当前请求来自浏览器还是客户端?我们可以从它的源代码中找到答案。
这段源代码来自于
Spring Boot的一个包
org.springframework.boot.autoconfigure.web中的
BasicErrorController,从类名就可以知道它是一个
Controller,且处理的路径就是“
/error”。找到错误处理的两个方法,如下图所示:
第一个方法和第二个方法处理的都是同一个
API,区别就在于第一个方法的
@RequestMapping里面包含一个
produces属性,它表示将生成什么类型的资源返回给前端,很明显,第一个方法要返回的是一个
HTML页面,而第二个方法返回的是
JSON数据。这就很明了了,当浏览器访问错误的
API的时候,会自动进入第一个方法处理错误,从客户端访问的时候,就会进入第二个方法处理错误。当然,从浏览器发送的请求的时候,我们可以看见请求头中看到浏览器要求的返回数据类型就包含了
text/html,如下图所示:
以上的例子都是访问资源不存在的案例,访问的处理逻辑并未进入对应的
Controller就被
Spring Boot打回去了,如果是服务代码抛出了异常,
Spring Boot是如何处理的呢?在这里我再写一个
Controller,手动抛出异常。代码如下:
@GetMapping("/user5") @ResponseBody public User user5() { throw new RuntimeException("User is not exist."); }
从浏览器端访问
http://localhost:8080/user5,返回的依然是
HTML页面,如下所示:
而从客户端访问,返回的依然是
JSON数据,如下图所示:
二、自定义服务异常处理
在实际的开发过程中,如果出现
404或者
500的错误的时候,返回给浏览器是
Spring Boot默认的处理界面,这并不友好,我们可以实现自定义页面来给出更好的温馨提示。
浏览器端自定义处理方式
这里仅仅介绍一种最简单的方式来处理异常,在
resources文件夹下再建立一个
resources文件夹,然后再在新建的
resources文件夹下建立一个
error,在
error文件夹里面建立
404.html和
500.html,在访问出现
404错误的时候,就会跳转到我们自己定义的
HTML中,而不是
Spring Boot默认的界面。
自定义服务异常处理类
在实际的开发中,我们完全可以自定义服务异常处理类,以满足实际的开发需求。这里写一个异常类,在业务逻辑处理中,可以根据需要手动抛出自己自定义的异常。比如:
package com.lemon.security.web.exception; import lombok.Data; import lombok.EqualsAndHashCode; /** * @author lemon * @date 2018/4/1 下午2:08 */ @EqualsAndHashCode(callSuper = true) @Data public class UserNotExistException extends RuntimeException { private Integer id; public UserNotExistException(Integer id) { super("user not exist."); this.id = id; } }
为了测试,在
Controller添加一个方法,代码如下:
@GetMapping("/user6/{id:\\d+}") @ResponseBody public User user6(@PathVariable Integer id) { throw new UserNotExistException(id); }
当访问这个
API的时候,就会抛出我们自定义的异常,这时候,
Spring Boot默认的处理方式返回的结果如下图:
有时候我们前端不需要这么多的信息,只需要部分信息,这个时候就需要自定义异常处理了,而不是采用
Spring Boot的默认处理方式了,在这里,我们可以写一个异常处理类,专门用来处理自定义异常。
package com.lemon.security.web.exception.handler; import com.lemon.security.web.exception.UserNotExistException; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import java.util.HashMap; import java.util.Map; /** * 自定义错误处理逻辑 * * @author lemon * @date 2018/4/1 下午2:48 */ @ControllerAdvice public class UserNotExistExceptionHandler { @ExceptionHandler(UserNotExistException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody public Map<String, Object> handleUserNotExistException(UserNotExistException ex) { Map<String, Object> result = new HashMap<>(); result.put("id", ex.getId()); result.put("message", ex.getMessage()); return result; } }
当一个类加上了
@ControllerAdvice注解,那么这个类就具备了处理其他
Controller异常的能力,具体的处理方式还是通过方法来进行的。上面的方法就是专门来处理
UserNotExistException这个异常的,
@ExceptionHandler就是指定了需要被处理的异常,
@ResponseStatus指定状态码,最后将处理后的数据返回。定义好这个类之后,当代码中抛出了
UserNotExistException异常的时候,都会转到这个方法中进行处理。再次运行应用,访问
http://localhost:8080/user6/1返回的数据如下如所示:
这就是我们自定义的异常处理后的数据了。
Spring Security技术栈开发企业级认证与授权系列文章列表:
Spring Security技术栈开发企业级认证与授权(一)环境搭建
Spring Security技术栈开发企业级认证与授权(二)使用Spring MVC开发RESTful API
Spring Security技术栈开发企业级认证与授权(三)表单校验以及自定义校验注解开发
Spring Security技术栈开发企业级认证与授权(四)RESTful API服务异常处理
Spring Security技术栈开发企业级认证与授权系列文章列表:
Spring Security技术栈开发企业级认证与授权(一)环境搭建
Spring Security技术栈开发企业级认证与授权(二)使用Spring MVC开发RESTful API
Spring Security技术栈开发企业级认证与授权(三)表单校验以及自定义校验注解开发
Spring Security技术栈开发企业级认证与授权(四)RESTful API服务异常处理
Spring Security技术栈开发企业级认证与授权(五)使用Filter、Interceptor和AOP拦截REST服务
Spring Security技术栈开发企业级认证与授权(六)使用REST方式处理文件服务
Spring Security技术栈开发企业级认证与授权(七)使用Swagger自动生成API文档
示例代码下载地址:
项目已经上传到码云,欢迎下载,内容所在文件夹为
chapter004。
相关文章推荐
- 认证鉴权与API权限控制在微服务架构中的设计与实现:授权码模式
- 007 使用SpringMVC开发restful API五--异常处理
- .NET开发中的事务处理大比拼 之 企业级服务COM+事务 (转)
- Spring Security技术栈开发企业级认证与授权(一)环境搭建
- JAVAWEB开发之SpringMVC详解(二)——高级开发、数据回显、参数绑定集合、图片上传、json交互、validation校验、异常处理、RESTful支持、拦截器
- Yii2框架之使用Restful自定义Api以及用户的授权认证
- .NET开发中的事务处理大比拼 之 企业级服务COM+事务
- spring cloud+.net core搭建微服务架构:Api授权认证(六)
- Spring Security技术栈开发企业级认证与授权(三)表单校验以及自定义校验注解开发
- SpringBoot构建RESTful API——处理返回异常
- spring cloud+.net core搭建微服务架构:Api授权认证(六)
- Yii2框架RESTful API教程(二) - 格式化响应,授权认证和速率限制
- Yii2框架RESTful API 格式化响应,授权认证和速率限制三部分详解
- .NET开发中的事务处理大比拼 之 企业级服务COM+事务
- java安全 ——JAAS(Java 认证和授权服务)开发指南
- Spring Security技术栈开发企业级认证与授权
- Spring Security技术栈开发企业级认证与授权
- GBIF处理、存储和认证服务gbif-annotation-processor介绍
- 企业级分布式应用服务EDAS——开发指南
- Dropwizard: 开发轻量RESTful服务