需求
最近笔者和前端同事在对接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) } }); })
后台接口
@CrossOrigin(origins = "*", maxAge = 3600) @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; }
为了防止看官看到代码馋,放出一部分代码
List<SnapShotDto> 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 = { "mapId": "china","debug":"true"};
我后台负责json输出的类是SnapShotDto,相关字段名是distName,这里完整对照了我的数据库语义。但是他想要显示的时候是name。
解决方法
distName加注解
@JsonProperty("name") @JsonInclude(JsonInclude.Include.NON_EMPTY) private String distName;
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": "西藏" } ] } }
本博客文章绝大多数为原创,少量为转载,代码经过测试验证,如果有疑问直接留言或者私信我。
创作文章不容易,转载文章必须注明文章出处;如果这篇文章对您有帮助,点击右侧打赏,支持一下吧。
创作文章不容易,转载文章必须注明文章出处;如果这篇文章对您有帮助,点击右侧打赏,支持一下吧。