项目中经常需要调用指定服务的接口,并且对返回的json结果数据,进行反序列化生成java类。
若是返回的数据格式固定,那么直接按照固定的格式进行反序列化生成java类便可。但是由于
返回的结果数据格式不固定,需要自己编写反序列化类进行分析。
下面我讲展示下项目中遇到的情况。
复制代码
{
"status": "200",
"Goal": {
"userId": "17090016",
"templateId": "26",
"templateName": "测试-营销通用目标模板",
"performance": [
{
"id": "8022",
"indexCode": "",
"name": "执行绩效综合达成率",
"category": "New Category",
"categoryName": "执行绩效",
"start": "2019-10-01T00:00:00.000",
"due": "2019-10-31T00:00:00.000",
"bizxTarget": "",
"bizxActual": "",
"done": "0.0",
"higedone": "",
"stateLabel": "重大延迟",
"weight": "",
"dataSource": "",
"lastModified": "2019-12-11T08:45:47.000",
"modifier": "17090016",
"children": ""
},
{
"id": "8015",
"indexCode": "",
"name": "协访达成率",
"category": "Goals",
"categoryName": "先决条件",
"start": "2019-10-01T00:00:00.000",
"due": "2019-10-31T00:00:00.000",
"bizxTarget": "47.0",
"bizxActual": "73.0",
"done": "0.0",
"higedone": "100.0",
"stateLabel": "重大延迟",
"weight": "",
"dataSource": "手持",
"lastModified": "2019-12-11T13:57:09.000",
"modifier": "17090016",
"children":
{
"childDescription": "CS协访",
"childTarget": "15",
"childActual": "18",
"childDone": "100.0"
}
},
{
"id": "8017",
"indexCode": "",
"name": "分销达成率",
"category": "New Category",
"categoryName": "执行绩效",
"start": "2019-10-01T00:00:00.000",
"due": "2019-10-31T00:00:00.000",
"bizxTarget": "100.0",
"bizxActual": "23.39",
"done": "23.39",
"higedone": "100.0",
"stateLabel": "重大延迟",
"weight": "20.0",
"dataSource": "订单管理",
"lastModified": "2019-12-11T14:09:32.000",
"modifier": "17090016",
"children": [
{
"childDescription": "门店数",
"childTarget": "",
"childActual": "23",
"childDone": ""
},
{
"childDescription": "门店品类数",
"childTarget": "",
"childActual": "31",
"childDone": ""
},
{
"childDescription": "门店SKU",
"childTarget": "",
"childActual": "25",
"childDone": ""
}
]
}
}
上面的json格式数据中,其余的字段格式都是比较的固定,但是可以看到children的数据内容出现了3种:
1、字符串内容
2、对象
3、数组
由于children的内容格式不固定,则直接利用jackson进行反序列化会失败,所以需要我们自己编写反序列化的实现类。
但是只是children的内容格式不固定,我们只是需要对children编写反序列化的实现类。
代码如下;
整个json对应的javabean
复制代码
package com.shinho.plrs.front.pojo;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@ApiModelProperty("id")
String id;
@ApiModelProperty("指标编码")
String code;
@JsonGetter("code")
public String getCode() {
return this.code;
}
@JsonSetter(value = "indexCode")
public void setCode(String code) {
this.code = code;
}
@ApiModelProperty("指标名称")
String purpose;
@ApiModelProperty("指标类型编码")
String category;
@ApiModelProperty("指标类型名称")
String categoryName;
@JsonProperty("start")
@ApiModelProperty("开始日期")
String startDate;
@JsonProperty("due")
@ApiModelProperty("结束日期")
String endDate;
@ApiModelProperty("目标")
String aim;
@ApiModelProperty("实际")
String acture;
@ApiModelProperty("达成率")
String done;
@ApiModelProperty("达成率封顶值")
String higedone;
@ApiModelProperty("状态(文本)")
String stateLabel;
@ApiModelProperty("权重")
String weight;
@ApiModelProperty("数据来源")
String dataSource;
@ApiModelProperty("最近修改时间")
String lastModified;
@ApiModelProperty("修改人")
String modifier;
// @ApiModelProperty("子指标数据")
// List childs = new ArrayList<>();
@ApiModelProperty("子指标数据")
@JsonDeserialize(using = ChildrenDeserializer.class)
List children;
}
复制代码
复制代码
package com.shinho.plrs.front.pojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
@ApiModelProperty("子指标描述")
String childDescription;
@ApiModelProperty("子指标目标")
String childTarget;
@ApiModelProperty("子指标完成值")
String childActual;
@ApiModelProperty("子指标达成率")
String childDone;
}
复制代码
反序列化类的实现:
复制代码
package com.shinho.plrs.front.pojo;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class ChildrenDeserializer extends StdDeserializer> {
public ChildrenDeserializer() {
super(List.class);
}
public ChildrenDeserializer(Class> vc) {
super(vc);
}
@Override
public List deserialize(JsonParser parser, DeserializationContext deserializer) throws IOException {
List list = new ArrayList<>();
if (StringUtils.isEmpty(parser.getText())) return list;
if (JsonToken.START_ARRAY.equals(parser.getCurrentToken())) {
while (!JsonToken.END_ARRAY.equals(parser.getCurrentToken())) {
list.add(parseJsonObjectToChild(parser));
parser.nextToken();
}
} else if (JsonToken.START_OBJECT.equals(parser.getCurrentToken())) {
list.add(parseJsonObjectToChild(parser));
}
return list;
}
/**
* 将json数据分析成java对象
*
* @param parser
* @return
*/
private Child parseJsonObjectToChild(JsonParser parser) throws IOException {
Child child = new Child();
JsonToken token = parser.getCurrentToken();
String fieldName = null;
while (!JsonToken.END_OBJECT.equals(token)) {
if (!JsonToken.FIELD_NAME.equals(token)) {
token = parser.nextToken();
continue;
}
fieldName = parser.getCurrentName();
token = parser.nextToken();
try {
BeanUtils.getPropertyDescriptor(Child.class, fieldName).getWriteMethod().invoke(child, parser.getText());
token = parser.nextToken();
} catch (Exception e) {
log.error("反序列化child过程中,出现异常:", e);
}
}
return child;
}
}