jackson 反序列化string_Jackson--反序列化的解析

项目中经常需要调用指定服务的接口,并且对返回的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;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值