需求
最近笔者和前端同事在对接restful接口,json数据格式如下:
json数据语义描述:
code:响应状态码,约定10001为成功。
message: 成功或者失败消息
result:响应结果集
其中一个节点含有mapId,这个mapId是他前端地图,行政区域对应的ID,我后台采集来的行政区域也有一套不同的数据层次。
(别问我为什么会有这种事,不同的省市级联,不同的业务情况下,数据关系及层级千差万别,我也不想出现这种问题,
增加彼此工作量还容易出现关联失败以及后续维护任务)
{
"code": 10001,
"message": "成功",
"data": {
"updateTime": "2020-02-23 13:43:18",
"result": [
{
"confirm": 93,
"dead": 0,
"heal": 57,
"weight": 77.25,
"mapId": "c3201",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 87,
"dead": 0,
"heal": 57,
"weight": 72.45,
"mapId": "c3205",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 79,
"dead": 0,
"heal": 67,
"weight": 66.55,
"mapId": "c3203",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 66,
"dead": 0,
"heal": 46,
"weight": 55.1,
"mapId": "c3208",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 55,
"dead": 0,
"heal": 41,
"weight": 46.05,
"mapId": "c3202",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 51,
"dead": 0,
"heal": 41,
"weight": 42.85,
"mapId": "c3204",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 48,
"dead": 0,
"heal": 25,
"weight": 39.65,
"mapId": "c3207",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 40,
"dead": 0,
"heal": 34,
"weight": 33.7,
"mapId": "c3206",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 37,
"dead": 0,
"heal": 29,
"weight": 31.05,
"mapId": "c3212",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 27,
"dead": 0,
"heal": 24,
"weight": 22.8,
"mapId": "c3209",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 23,
"dead": 0,
"heal": 17,
"weight": 19.25,
"mapId": "c3210",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 13,
"dead": 0,
"heal": 11,
"weight": 10.95,
"mapId": "c3213",
"updateTime": "2020-02-25 18:17:14"
},
{
"confirm": 12,
"dead": 0,
"heal": 10,
"weight": 10.1,
"mapId": "c3211",
"updateTime": "2020-02-25 18:17:14"
}
]
}
}
前端调用方式
$(function () {
var json = { "mapId": "china"};
$.ajax({
url: "/data/query",
contentType: 'application/json',
data: JSON.stringify(json),
type: "post",
dataType: "json",
success: function(data) {
var code = data.code;
var message = data.message;
var updatetime = data.data.updateTime;
var result = data.data.result;
if(code== 10001)
{
console.log(message);
console.log("最后一次更新日期:",updatetime);
console.log("查询的数据如下:",result);
}else
{
console.log(message);
}
},
error:function (err) {
console.log(err)
}
});
})
后台接口
)
@PostMapping(value = "query", consumes = "application/json", produces = "application/json")
@ResponseBody
public JsonResult query(@RequestBody MapQueryParam param, HttpServletResponse response)
{
response.setHeader("Access-Allow-Control-Origin","*");
response.setHeader("Access-Control-Allow-Headers","*");
response.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, OPTIONS");
String mapId = param.getMapId();
if(Objects.isNull(mapId))
{
return errorResult("地图模型载入失败");
}
List<SnapShotDto> list = handleInternal(param);
if(Objects.isNull(list))
{
return errorResult("地图模型载入失败");
}
String lastUpdateTime = statusService.queryStatus("lastUpdateTime");
return successResult("成功", ImmutableMap.of("updateTime",lastUpdateTime,"result",list));
}
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class MapQueryParam {
private String mapId;
private Boolean debug;
private Integer distId;
}
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.netmarch.covid19.entity.SnapShot;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class SnapShotDto extends SnapShot {
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String distName;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String riskColor;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Integer parentId;
}
为了防止看官看到代码馋,放出一部分代码
handleInternal(MapQueryParam param)
{
String mapId = param.getMapId();
if("china".equals(mapId))
{
return dataService.listProvince1(param);
}
ByteDanceDistrict dist = districtService.findDistrictByMapId(mapId);
if(Objects.isNull(dist)) {
return null;
}
String level = dist.getLevel();
Integer distId = dist.getId();
param.setDistId(distId);
if(Objects.isNull(level)) {
return null;
}
if("province".equals(level)) {
return dataService.queryCity1(param);
}
if("city".equals(level)) {
return dataService.queryArea1(param);
}
return dataService.queryArea1(param);
}
public List<SnapShotDto> queryCity1(MapQueryParam param) {
Integer provinceId = param.getDistId();
final Boolean debug = Optional.ofNullable(param.getDebug()).orElse(false);
List<SnapShot> snapshots = queryCity1(provinceId);
return snapshots.parallelStream().map(snapShot -> {
SnapShotDto dto = new SnapShotDto();
BeanUtils.copyProperties(snapShot,dto,Arrays.asList(copyFields));
if (!debug) {
return dto;
}
final Integer distId = snapShot.getDistId();
Optional<ByteDanceDistrict> opt = cities.parallelStream().filter(city -> city.getId().equals(distId)).findFirst();
if(opt.isPresent()) {
dto.setDistName(opt.get().getName());
}
return dto;
}).collect(Collectors.toList());
}
@Override
public List<SnapShot> queryCity1(Integer provinceId) {
List<Integer> cityIds = cities.parallelStream().filter(city -> {
return city.getParentId().equals(provinceId);
}).map(city -> {
return city.getId();
}).collect(Collectors.toList());
if(CollectionUtils.isEmpty(cityIds)) {
return Collections.emptyList();
}
return snapshotService.queryByDistIds(cityIds);
//return snapshotService.queryByDistIds(filterSubDistIds(provinceId,cities));
现在他向在resutl数组的任意一个节点中{}添加name,方便调试。
最终期望格式如下:
{
"confirm": 64786,
"dead": 2563,
"heal": 18916,
"weight": 53159.1,
"mapId": "hubei",
"updateTime": "2020-02-25 18:17:14",
"name": "湖北"
}
于是给他了一个调试参数 debug,这个参数可选,
debug不填写,默认false,或者debug填写false,也不输出调试信息
于是前面json 变成如下
var
我后台负责json输出的类是SnapShotDto,相关字段名是distName,这里完整对照了我的数据库语义。但是他想要显示的时候是name。
解决方法
distName加注解
@JsonProperty("name")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private
springMVC/springboot中默认使用Jackson对json进行序列化及反序列化。所以以上使用的是jackson的注解
客户端最终得到的json格式如下
{
"code": 10001,
"message": "成功",
"data": {
"updateTime": "2020-02-23 13:43:18",
"result": [
{
"confirm": 64786,
"dead": 2563,
"heal": 18916,
"weight": 53159.1,
"mapId": "hubei",
"updateTime": "2020-02-25 18:17:14",
"name": "湖北"
},
{
"confirm": 1347,
"dead": 7,
"heal": 822,
"weight": 1119.75,
"mapId": "guangdong",
"updateTime": "2020-02-25 19:27:24",
"name": "广东"
},
{
"confirm": 1271,
"dead": 19,
"heal": 1000,
"weight": 1069.65,
"mapId": "henan",
"updateTime": "2020-02-25 18:17:14",
"name": "河南"
},
{
"confirm": 1205,
"dead": 1,
"heal": 808,
"weight": 1004.55,
"mapId": "zhejiang",
"updateTime": "2020-02-25 18:17:14",
"name": "浙江"
},
{
"confirm": 1016,
"dead": 4,
"heal": 766,
"weight": 851.7,
"mapId": "hunan",
"updateTime": "2020-02-25 19:27:24",
"name": "湖南"
},
{
"confirm": 989,
"dead": 6,
"heal": 713,
"weight": 827.75,
"mapId": "anhui",
"updateTime": "2020-02-25 18:17:14",
"name": "安徽"
},
{
"confirm": 934,
"dead": 1,
"heal": 682,
"weight": 781.45,
"mapId": "jiangxi",
"updateTime": "2020-02-25 18:17:14",
"name": "江西"
},
{
"confirm": 756,
"dead": 6,
"heal": 349,
"weight": 623.15,
"mapId": "shandong",
"updateTime": "2020-02-25 18:17:14",
"name": "山东"
},
{
"confirm": 631,
"dead": 0,
"heal": 459,
"weight": 527.75,
"mapId": "jiangsu",
"updateTime": "2020-02-25 18:17:14",
"name": "江苏"
},
{
"confirm": 576,
"dead": 6,
"heal": 349,
"weight": 479.15,
"mapId": "chongqing",
"updateTime": "2020-02-25 18:17:14",
"name": "重庆"
},
{
"confirm": 529,
"dead": 3,
"heal": 288,
"weight": 438.05,
"mapId": "sichuan",
"updateTime": "2020-02-25 19:27:24",
"name": "四川"
},
{
"confirm": 480,
"dead": 12,
"heal": 241,
"weight": 397.85,
"mapId": "heilongjiang",
"updateTime": "2020-02-25 18:17:14",
"name": "黑龙江"
},
{
"confirm": 400,
"dead": 4,
"heal": 215,
"weight": 331.35,
"mapId": "beijing",
"updateTime": "2020-02-25 18:17:14",
"name": "北京"
},
{
"confirm": 336,
"dead": 3,
"heal": 268,
"weight": 282.65,
"mapId": "shanghai",
"updateTime": "2020-02-25 18:17:14",
"name": "上海"
},
{
"confirm": 311,
"dead": 6,
"heal": 245,
"weight": 261.95,
"mapId": "hebei",
"updateTime": "2020-02-25 19:27:24",
"name": "河北"
},
{
"confirm": 294,
"dead": 1,
"heal": 199,
"weight": 245.3,
"mapId": "fujian",
"updateTime": "2020-02-25 19:27:24",
"name": "福建"
},
{
"confirm": 252,
"dead": 2,
"heal": 147,
"weight": 209.25,
"mapId": "guangxi",
"updateTime": "2020-02-25 18:17:14",
"name": "广西"
},
{
"confirm": 245,
"dead": 1,
"heal": 185,
"weight": 205.4,
"mapId": "shaanxi",
"updateTime": "2020-02-25 19:02:15",
"name": "陕西"
},
{
"confirm": 174,
"dead": 2,
"heal": 129,
"weight": 145.95,
"mapId": "yunnan",
"updateTime": "2020-02-25 18:17:14",
"name": "云南"
},
{
"confirm": 168,
"dead": 5,
"heal": 124,
"weight": 141.35,
"mapId": "hainan",
"updateTime": "2020-02-25 18:17:14",
"name": "海南"
},
{
"confirm": 146,
"dead": 2,
"heal": 104,
"weight": 122.3,
"mapId": "guizhou",
"updateTime": "2020-02-25 18:17:14",
"name": "贵州"
},
{
"confirm": 135,
"dead": 3,
"heal": 91,
"weight": 113,
"mapId": "tianjin",
"updateTime": "2020-02-25 19:27:24",
"name": "天津"
},
{
"confirm": 133,
"dead": 0,
"heal": 96,
"weight": 111.2,
"mapId": "shanxi",
"updateTime": "2020-02-25 18:17:14",
"name": "山西"
},
{
"confirm": 121,
"dead": 1,
"heal": 84,
"weight": 101.15,
"mapId": "liaoning",
"updateTime": "2020-02-25 18:17:14",
"name": "辽宁"
},
{
"confirm": 93,
"dead": 1,
"heal": 62,
"weight": 77.65,
"mapId": "jilin",
"updateTime": "2020-02-25 18:17:14",
"name": "吉林"
},
{
"confirm": 91,
"dead": 2,
"heal": 80,
"weight": 77.1,
"mapId": "gansu",
"updateTime": "2020-02-25 18:17:14",
"name": "甘肃"
},
{
"confirm": 84,
"dead": 2,
"heal": 19,
"weight": 68.45,
"mapId": "xianggang",
"updateTime": "2020-02-25 18:17:14",
"name": "香港"
},
{
"confirm": 76,
"dead": 2,
"heal": 30,
"weight": 62.6,
"mapId": "xinjiang",
"updateTime": "2020-02-25 18:17:14",
"name": "新疆"
},
{
"confirm": 75,
"dead": 0,
"heal": 34,
"weight": 61.7,
"mapId": "neimenggu",
"updateTime": "2020-02-25 18:17:14",
"name": "内蒙古"
},
{
"confirm": 71,
"dead": 0,
"heal": 61,
"weight": 59.85,
"mapId": "ningxia",
"updateTime": "2020-02-25 18:17:14",
"name": "宁夏"
},
{
"confirm": 31,
"dead": 1,
"heal": 5,
"weight": 25.2,
"mapId": "taiwan",
"updateTime": "2020-02-25 18:17:14",
"name": "台湾"
},
{
"confirm": 18,
"dead": 0,
"heal": 18,
"weight": 15.3,
"mapId": "qinghai",
"updateTime": "2020-02-25 18:17:14",
"name": "青海"
},
{
"confirm": 10,
"dead": 0,
"heal": 6,
"weight": 8.3,
"mapId": "aomen",
"updateTime": "2020-02-25 18:17:14",
"name": "澳门"
},
{
"confirm": 1,
"dead": 0,
"heal": 1,
"weight": 0.85,
"mapId": "xizang",
"updateTime": "2020-02-25 18:17:14",
"name": "西藏"
}
]
}
}