上一个教程我们讲解如何配置MyBatis根据数据库类型进行对应数据库方言自动分页查询,本次我们将接着以往教程的成果来整合配置SpringMVC以及配置我们自定义的FastJSON序列输出,如需看上篇教程的同学可点击链接
【Spring Boot从入门到进阶教程系列 -- MyBatis分页拦截器实现(包含数据库方言)】
下面我们直接开启代码之旅
我们通过@ResponseBody返回对象的JSON字符串,如下示例
请求方法
@ResponseBody
@RequestMapping("/findOne")
public Map findOne() throws BizErrorEx {
Map<String, Object> map = new HashMap<>();
map.put("id", 10001);
map.put("name", "张三");
map.put("sex", 1);
map.put("ctime", System.currentTimeMillis());
return map;
}
页面输出
{
"sex":1,
"name":"张三",
"ctime":1529545916866,
"id":10001
}
通过以上我们可以看出@ResponseBody会把对象转化成字符串输出到前端,但是这一般不能满足我们的日常开发需求,例如我们经常需要的结构如下示例,其中包含基础的业务响应状态,HTTP状态,还有异常信息,响应时间等
{
"code":"000000",
"data":{
"sex":1,
"name":"张三",
"ctime":1529545916866,
"id":10001
},
"http":{
"message":"OK",
"status":200
},
"msg":"操作成功",
"ts":1529545916867
}
通过以上代码演示,我们如何优雅,简洁不入侵业务代码的情况下完成我们的设计改造呢?下面我们开始尝试完成以上的设计需求实现
步骤1. 编写一个返回对象的包装实体类
public class RetData<T> implements Serializable {
public String code; // 业务状态
public String msg; // 业务信息
public long ts; // 响应时间
public T data; // 业务响应数据实体
public Map<String, Object> http = new HashMap<>(); // HTTP状态,信息参数
public RetData() {
}
public RetData(String code, String msg, T data) {
this(code, msg, System.currentTimeMillis(), data, HttpStatus.OK);
}
public RetData(String code, String msg, T data, HttpStatus httpStatus) {
this(code, msg, System.currentTimeMillis(), data, httpStatus);
}
public RetData(String code, String msg, long ts, T data, HttpStatus httpStatus) {
this.code = code;
this.msg = msg;
this.ts = ts;
this.data = data;
httpStatus = httpStatus == null ? HttpStatus.OK : httpStatus;
http.put("status", httpStatus.value());
http.put("message", httpStatus.getReasonPhrase());
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public long getTs() {
return ts;
}
public void setTs(long ts) {
this.ts = ts;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
步骤2. 通过查看FastJSON源码并改造writeInternal方法,加入响应实体包装业务实体的操作
核心代码
protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
ByteArrayOutputStream outnew = new ByteArrayOutputStream();
try {
HttpHeaders headers = outputMessage.getHeaders();
SerializeFilter[] globalFilters = this.fastJsonConfig.getSerializeFilters();
List<SerializeFilter> allFilters =