springboot返回的正常响应数据是json格式的数据,可是……………。 如果服务内部故障呢,或者参数异常,这时候返回的是html数据。非常的不方便。
那怎么办?
拦截异常响应,并进行改写。
比如我的请求为(userid期望是数字,输入不是数字):
http://localhost:9876/api/user4?userid=23d
异常响应码为:
{
code: 200,
message: "Number convert exception",
url: "http://localhost:9876/api/user4"
}
如果输入为:
http://localhost:9876/api/user4?userid=23
正常响应为:
{
code: 0,
data: {
userId: 23,
userName: "hello",
userPass: "world"
}
}
关键:@RestControllerAdvice
spring.mvc.throw-exception-if-no-handler-found=true
反序列化的时候,null字段别反序列化了。
spring.jackson.serialization-inclusion=NON_NULL
也可以这么干。不返回null字段
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiResult<T> {
public int code = 0;
public String message;
public String error;
public T data;
}
说明:上面的方法,data字段,还是会返回null的。如果在data里面想不返回null,需要在data的类定义上加上注解。 如下所示 。
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public class User {
private int userId;
private String userName;
private String userPass;
}
如下所示。
@RequestMapping("/user4")
public ApiResult<User> user4( @RequestParam("userid")String userid ) throws MyException{
ApiResult<User> result = new ApiResult<User>();
User user = new User();
int id = 0;
try {
id = Integer.valueOf(userid);
}catch(Exception e){
throw new MyException("Number convert exception"); // 看这里啊!!!!!!!!!!!!
}
user.setUserId(id);
user.setUserName("hello");
user.setUserPass("world");
result.data = user;
return result;
}
不要去试TypeMismatchException,NumberFormatException,没戏。还是老实 将string 转为int吧。系统的错误,通过GlobalExceptionHandler是捕猎不到的。
如下所示。
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = MyException.class)
public ErrorResult handleBadRequest(HttpServletRequest req, MyException ex) {
ErrorResult result = new ErrorResult();
result.code=200;
result.message=ex.getMessage();
result.url = req.getRequestURL().toString();
return result;
}
}
- null字段别反序列化了
- 系统异常,转化为自定义异常,更可控
- url如果是数字参数,请使用正则表达式,更安全
@RequestMapping("/user/{userId:\\d+}")
public ApiResult<User> user(@PathVariable("userId")String userid) throws MyException{
}
Q: 404,这时候,app拿到这个返回,会无语的,怎么搞呢?
A: 重写/error接口
@RestController
public class HttpErrorHandler implements ErrorController {
private final static String ERROR_PATH = "/error";
@RequestMapping(value = ERROR_PATH)
@ResponseBody
public Object error(HttpServletRequest request) {
ErrorResult result = new ErrorResult();
result.code=404;
result.message="not found(404)";
result.url=request.getRequestURL().toString();
return result;
}
@Override
public String getErrorPath() {
return ERROR_PATH;
}
}
Q: 不同的用户,权限不一样,有些人有查看的权限,有些人有修改的权限,有些人的删除的权限,如何搞
A: 通过拦截机制,搞,思路如下。
- token机制
- 路由
- 规则引擎
1. 用户登陆,换token 2. 用户以后的请求,带上token 3. url拦截,查token,通过token,查路由表 4. 根据路由规则,决定是放还是弃
很简单,对吧。
原理列表
- swagger
- swagger-ui web server
- api service
swagger是api文档一体化的一种方案.
api service返回swagger.json数据.
swagger-ui-web server解析swagger.json数据.进行页面展示.
使用swagger即可.
需要部署swagger-ui服务器,将url指向本服务localhost:8888/api-docs即可.
小坑如下:
否则,swagger-ui服务器无法获得后端请求数据.
// 配置跨域
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
改一下url即可.
const ui = SwaggerUIBundle({
//url: "http://petstore.swagger.io/v2/swagger.json",
url: "http://localhost:9876/api-docs",
- @Api 作用在控制器上
- @ApiModel 作用在model class上面
- @ApiModelProperty 作用在model class里面的属性上面
- @ApiOperation 作用的requestMapping上面.
- @ApiResponses 描述该API操作可能出现的异常情况。
- @ApiParam 描述该API操作接受的参数类型