共计 5075 个字符,预计需要花费 13 分钟才能阅读完成。
在我的项目开发中,接口与接口之间、前后端之间的数据传输都应用 JSON 格局。
1 fastjson 应用
阿里巴巴的 fastjson 是目前利用最宽泛的 JSON 解析框架。本文也将应用 fastjson。
1.1 引入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.35</version>
</dependency>
复制代码
2 对立封装返回数据
在 web 我的项目中,接口返回数据个别要蕴含状态码、信息、数据等,例如上面的接口示例:
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
- @author guozhengMu
- @version 1.0
- @date 2019/8/21 14:55
- @description
- @modify
*/
@RestController
@RequestMapping(value = “/test”, method = RequestMethod.GET)
public class TestController {
@RequestMapping("/json")
public JSONObject test() {JSONObject result = new JSONObject();
try {
// 业务逻辑代码
result.put("code", 0);
result.put("msg", "操作胜利!");
result.put("data", "测试数据");
} catch (Exception e) {result.put("code", 500);
result.put("msg", "零碎异样,请分割管理员!");
}
return result;
}
}
复制代码
这样的话,每个接口都这样解决,十分麻烦,须要一种更优雅的实现形式。
2.1 定义对立的 JSON 构造
对立的 JSON 构造中属性包含数据、状态码、提示信息,其余项能够本人依据须要增加。一般来说,应该有默认的返回构造,也应该有用户指定的返回构造。因为返回数据类型无奈确定,须要应用泛型,代码如下:
public class ResponseInfo<T> {
/**
* 状态码
*/
protected String code;
/**
* 响应信息
*/
protected String msg;
/**
* 返回数据
*/
private T data;
/**
* 若没有数据返回,默认状态码为 0,提示信息为“操作胜利!”*/
public ResponseInfo() {
this.code = 0;
this.msg = "操作胜利!";
}
/**
* 若没有数据返回,能够人为指定状态码和提示信息
* @param code
* @param msg
*/
public ResponseInfo(String code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 有数据返回时,状态码为 0,默认提示信息为“操作胜利!”* @param data
*/
public ResponseInfo(T data) {
this.data = data;
this.code = 0;
this.msg = "操作胜利!";
}
/**
* 有数据返回,状态码为 0,人为指定提示信息
* @param data
* @param msg
*/
public ResponseInfo(T data, String msg) {
this.data = data;
this.code = 0;
this.msg = msg;
}
// 省略 get 和 set 办法
}
复制代码
2.2 应用对立的 JSON 构造
咱们封装了对立的返回数据结构后,在接口中就能够间接应用了。如下:
import com.example.demo.model.ResponseInfo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
- @author guozhengMu
- @version 1.0
- @date 2019/8/21 14:55
- @description
- @modify
*/
@RestController
@RequestMapping(value = “/test”, method = RequestMethod.GET)
public class TestController {
@RequestMapping("/json")
public ResponseInfo test() {
try {
// 模仿异样业务代码
int num = 1 / 0;
return new ResponseInfo("测试数据");
} catch (Exception e) {return new ResponseInfo(500, "零碎异样,请分割管理员!");
}
}
}
复制代码
如上,接口的返回数据处理便优雅了许多。针对下面接口做个测试,启动我的项目,通过浏览器拜访:localhost:8096/test/json,失去响应后果:
{“code”:500,”msg”:” 零碎异样,请分割管理员!”,”data”:null}
复制代码
3 全局异样解决
3.1 零碎定义异样解决
新建一个 ExceptionHandlerAdvice 全局异样解决类,而后加上 @RestControllerAdvice 注解即可拦挡我的项目中抛出的异样,如下代码中蕴含了几个异样解决,如参数格局异样、参数缺失、零碎异样等,见下例:
@RestControllerAdvice
@Slf4j
public class ExceptionHandlerAdvice {
// 参数格局异样解决
@ExceptionHandler({IllegalArgumentException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseInfo badRequestException(IllegalArgumentException exception) {log.error("参数格局不非法:" + e.getMessage());
return new ResponseInfo(HttpStatus.BAD_REQUEST.value() + ""," 参数格局不符!");
}
// 权限有余异样解决
@ExceptionHandler({AccessDeniedException.class})
@ResponseStatus(HttpStatus.FORBIDDEN)
public ResponseInfo badRequestException(AccessDeniedException exception) {return new ResponseInfo(HttpStatus.FORBIDDEN.value() + "", exception.getMessage());
}
// 参数缺失异样解决
@ExceptionHandler({MissingServletRequestParameterException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseInfo badRequestException(Exception exception) {return new ResponseInfo(HttpStatus.BAD_REQUEST.value() + ""," 短少必填参数!");
}
// 空指针异样
@ExceptionHandler(NullPointerException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseInfo handleTypeMismatchException(NullPointerException ex) {log.error("空指针异样,{}", ex.getMessage());
return new JsonResult("500", "空指针异样");
}
@ExceptionHandler(Exception.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public JsonResult handleUnexpectedServer(Exception ex) {log.error("零碎异样:", ex);
return new JsonResult("500", "零碎产生异样,请分割管理员");
}
// 零碎异样解决
@ExceptionHandler(Throwable.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseInfo exception(Throwable throwable) {log.error("零碎异样", throwable);
return new ResponseInfo(HttpStatus.INTERNAL_SERVER_ERROR.value() + "零碎异样,请分割管理员!");
}
}
复制代码
@RestControllerAdvice 注解蕴含了 @Component 注解,阐明在 Spring Boot 启动时,也会把该类作为组件交给 Spring 来治理。
@RestControllerAdvice 注解蕴含了 @ResponseBody 注解,为了异样解决完之后给调用方输入一个 JSON 格局的封装数据。
@RestControllerAdvice 注解还有个 basePackages 属性,该属性用来拦挡哪个包中的异样信息,个别咱们不指定这个属性,咱们拦挡我的项目工程中的所有异样。
在办法上通过 @ExceptionHandler 注解来指定具体的异样,而后在办法中解决该异样信息,最初将后果通过对立的 JSON 构造体返回给调用者。
但在我的项目中,咱们个别都会比拟具体地去拦挡一些常见异样,拦挡 Exception 尽管能够一劳永逸,然而不利于咱们去排查或者定位问题。理论我的项目中,能够把拦挡 Exception 异样写在 GlobalExceptionHandler 最上面,如果都没有找到,最初再拦挡一下 Exception 异样,保障输入信息敌对。
上面咱们通过一个接口来进行测试:
@RestController
@RequestMapping(value = “/test”, method = RequestMethod.POST)
public class TestController {
@RequestMapping("/json")
public ResponseInfo test(@RequestParam String userName, @RequestParam String password) {
try {
String data = "登录用户:" + userName + ",明码:" + password;
return new ResponseInfo("0", "操作胜利!", data);
} catch (Exception e) {return new ResponseInfo("500", "零碎异样,请分割管理员!");
}
}
}
复制代码
接口调用,password 这项成心空缺:
最初
如果你感觉此文对你有一丁点帮忙,点个赞。或者能够退出我的开发交换群:1025263163 互相学习,咱们会有业余的技术答疑解惑
如果你感觉这篇文章对你有点用的话,麻烦请给咱们的开源我的项目点点 star:http://github.crmeb.net/u/defu 不胜感激!
PHP 学习手册:https://doc.crmeb.com
技术交换论坛:https://q.crmeb.com