java 自定义json解析注解 复杂json解析 工具类

article/2025/11/10 18:01:35

java 自定义json解析注解 复杂json解析 工具类

目录

  • java 自定义json解析注解 复杂json解析 工具类
    • 1.背景
    • 2、需求-各式各样的json
      • 一、一星难度json【json对象中不分层】
      • 二、二星难度json【json对象中出现层级】
      • 三、三星难度json【json对象中存在数组】
      • 四、四星难度json【json对象中数组中存在层级】
      • 五、五星难度json【json对象中包含数组、且选择是存在底层级跳转到高层级的】
      • 六、利用自定义注解和配置类解析
        • 1.自定义注解类
        • 2.自定义注解对应解析工具类【重点】
        • 3.如果业务中json的key出现了 > 这种特殊符合(并且前后带空格的)可以替换。如下:
      • 七、实战 某个业务场景的一段json

文章链接 https://blog.csdn.net/wuyuanshun/article/details/128498372
此文章链接: 复杂json解析

1.背景

为什么要写这个自定义注解,因为需求需要处理一批比较复杂的json(如果只有一个,直接手动写代码解析就好),众所周知批量且类似的工作,最好抽象出来。这也符合编程的风格,不重复造轮子,但是需要造轮子。【前面铺垫比较长,如果需求比较复杂的json可以直接划到最下面,粘贴自定义注解类 和 自定义注解解析工具类】

2、需求-各式各样的json

一、一星难度json【json对象中不分层】

需要的字段也恰好是对应上的
json

{
"name": "wuyuanshun",
"sex":"男"
}[
{
"name": "wuyuanshun",
"sex":"男"
},
{
"name": "liuyuanshun",
"sex":"男"
}
]

java对象

@Data
public class Bean {private String name;private String sex;}

解析方法

public class JsonUtil {public static final ObjectMapper mapper = new ObjectMapper();public static <T> T fromJson(String json, Class<T> clazz) {requireNonNull(json);requireNonNull(clazz);try {return mapper.readValue(json, clazz);} catch (IOException e) {throw new RuntimeException(e);}}/*** json数组转java对象* @param json* @param valueType* @param <T>* @return* @author: wuyuanshn*/public static <T> List<T> jsonArrayToObjectList(String json, Class<T> valueType)  {try {//解析JSONArray redisJsonArray = JSONArray.parseArray(json);List<T> redisList = new ArrayList<>(redisJsonArray.size());//封装for (int i = 0; i < redisJsonArray.size(); i++) {T item = mapper.readValue(redisJsonArray.getString(i), valueType);redisList.add(item);}//返回return redisList;} catch (Exception e) {return null;}}public static void main(String[] args) {String json="xxx";Bean bean = fromJson(json, Bean.class);System.out.println(bean);String jsonList="[xxx,xxx]";List<Bean> beanList = jsonArrayToObjectList(jsonList, Bean.class);System.out.println(beanList);}
}

二、二星难度json【json对象中出现层级】

难度加大一些,比如,出现了层级
json

{
"name": "wuyuanshun",
"sex":"男","like":{"title":"羽毛球","level":1,"time":1672402865000
}
}

简单解析的话,我们可以再新建一个Like对象,如:

@Data
public class Like {private String title;private Integer level;private Long time;
}

然后再bean里加上Like对象即可:

java对象

public class Bean {private String name;private String sex;private Like like;
}

不过需求真的会那么简单,我就不需要写这个文章了。像闯关一下,让我们提升难度,
比如我需要的对象是要同一层级的(如下),要存在一起(比如存数据库表)。当然我们也可以建Like对象再通过代码导入到同一层级。不过我们可以让他简单一些(正题开始了):
对应解析java对象

@Date
public class Bean {@JsonAnalysisProperty("name")private String name;@JsonAnalysisProperty("sex")private String sex;@JsonAnalysisProperty("like > title")private String likeTitle;@JsonAnalysisProperty("like > level")private Integer likeLevel;@JsonAnalysisProperty("like > time")private Long likeTime;
}

对应解析的bean【自定义注解@JsonAnalysisProperty在文章最下面 目录六】

  • name 单层级直接获取
  • like > title 多层级 用 > 隔断取下一层级内容 【注意 > 前后有空格】

*测试方法【之后每个测试用测方法】

public static void main(String[] args) {//jsonString json = "{xxxxxxxxxxx}";//自定义对象Bean bean = new Bean();JsonAnalysisPropertyConfig.setObjectByJsonAnalysis(bean,json);System.out.println(bean);//此文章链接: [复杂json解析] https://blog.csdn.net/wuyuanshun/article/details/128498372}
}

三、三星难度json【json对象中存在数组】

需求取出姓名、性别、爱好名称(like > title)、语文分数。

{"name":"wuyuanshun","sex":"男","like":{"title":"羽毛球","level":1,"time":1672402865000},"examination_results":[{"subject":"数学","date":"2023-01-29","score":98.5},{"subject":"语文","date":"2023-01-29","score":98.5},{"subject":"英语","date":"2023-01-29","score":98.5}]
}

对应解析java对象

@Date
public class Bean {@JsonAnalysisProperty("name")private String name;@JsonAnalysisProperty("sex")private String sex;@JsonAnalysisProperty("like > title")private String likeTitle;@JsonAnalysisProperty("like > level")private Integer likeLevel;@JsonAnalysisProperty("examination_results >> \"subject\":\"语文\" > score")private Double chineseScore;
}

>> 代表之后是数组中的内容,直到"key": "value"这种选择器结束。如果数组到选择器key:value中还有层级,原来的层级( > )需要换成 (>>),如四星难度json。【注意 >> 前后有空格】

  • examination_results >> “subject”:“语文” 找到examination_results数组中key:value为"subject":"语文“的json对象
  • > score 继续在json对象层级里找到score的值98.5

四、四星难度json【json对象中数组中存在层级】

需求是取index_display 为 "有互动人数"的数组中的value数值。


{"purchase_crowd":{"interact_data":[{"index_value":{"index_display":"有互动人数","value":{"value":44,"unit":"number"},},"show_list":[{"display":"首购人数占比","value":{"value":0.5909090909090909}}]},{"index_value":{"index_display":"无互动人数"},"show_list":[{"display":"xxx占比","value":{"value":0.02}},{"display":"首购人数占比","value":{"value":0.4444444444444444}}]}]}
}

对应解析java对象

@Date
public class Bean {@JsonAnalysisProperty(defaultValue = "0",value = "purchase_crowd > interact_data >> index_value >> \"index_display\":\"有互动人数\" > value > value") @ApiModelProperty("有互动人数") private String purchaseCrowdInteractDataPeopleNumberInteracting;}
  • defaultValue = “0” 是如果json解析中没找到这个字段添加的默认值。
  • interact_data >> index_value >> “index_display”:“有互动人数” 这一段都是在数组中选择某一个key:value,来定位自己要找的json对象。找到key:value后,默认在当前层级继续向下选择
  • value > value 找到值44。

五、五星难度json【json对象中包含数组、且选择是存在底层级跳转到高层级的】

json同上
如 需求是取index_display 为 "有互动人数"的数组中的 ‘收购人数占比’ value数值、
和取index_display 为 "无互动人数"的数组中的‘收购人数占比’value数值

对应解析java对象

@Date
public class Bean {@JsonAnalysisProperty(defaultValue = "0",value = "purchase_crowd > interact_data >> * index_value >> \"index_display\":\"有互动人数\" > show_list >> \"display\":\"首购人数占比\" > value > value") @ApiModelProperty("有互动人数-首购人数占比") private String purchaseCrowdInteractDataPeopleNumberFirstPurchaseRatio;@JsonAnalysisProperty(defaultValue = "0",value = "purchase_crowd > interact_data >> * index_value >> \"index_display\":\"无互动人数\" > show_list >> \"display\":\"首购人数占比\" > value > value") @ApiModelProperty("无互动人数-首购人数占比") private String purchaseCrowdNotInteractDataPeopleNumberFirstPurchaseRatio;
}

自定义注解的逻辑就是像指针一样根据注解中的路由去寻找字段

符号 “ * ” 代表记录指针位置层级,等找到对应的key:value时,返回之前保存的层级。【注意 * 前后有空格】

  • interact_data >> * index_value >> “index_display”:“无互动人数” 中的 * 号记录了找到key:value后从 interact_data到 index_value这层开始选择可以继续选择【index_value、show_list】,及通过之前的选择选中了下图中绿色区域。
  • > show_list >> “display”:“首购人数占比” 继续从show_list数组中找到对应的key:value(黄色区域)
  • > value > value 继续从‘首购人数占比’层级往下寻找 到0.4444…。
    在这里插入图片描述

六、利用自定义注解和配置类解析

 public static void main(String[] args) {//jsonString json = "{xxxxxxxxxxx}";//自定义对象Bean bean = new Bean();JsonAnalysisPropertyConfig.setObjectByJsonAnalysis(bean,json);System.out.println(bean);//此文章链接 https://blog.csdn.net/wuyuanshun/article/details/128498372}
}

1.自定义注解类


package com.wuyuanshun.annotation;import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @program: wys-service* @description: 自定义json解析注解* @author: wuyuanshn* @create: 2022-12-26 17:12**/@Target({java.lang.annotation.ElementType.ANNOTATION_TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface JsonAnalysisProperty {/*** 正常层级选择*/String SPLIT_DEFAULT = " > ";/*** 下层级是数组内元素*/String SPLIT_DEFAULT_ARRAY = " >> ";/*** 数组内 选择返回的层级 默认是最后(最深层)的节点*/String SELECT_ARRAY_DEFAULT_ARRAY = "* ";/*** 核心字段** @return*/String value();/*** 类型 默认0* 1 多层级【后续可以改为枚举类型】** @return*/int type() default 0;/*** 分隔符** @return*/String split() default SPLIT_DEFAULT;/*** 数组内 选择返回的层级 默认是最后(最深层)的节点** @return*/String selectArrayOne() default SELECT_ARRAY_DEFAULT_ARRAY;/*** 标记为数组** @return*/String splitArray() default SPLIT_DEFAULT_ARRAY;/*** 是否忽略** @return*/boolean ignore() default false;/*** 默认值** @return*/String defaultValue() default "";
}

2.自定义注解对应解析工具类【重点】

以下代码是此篇文章的核心重点,添加了解释代码的注释便于大家理解和修改升级。

package com.wuyuanshun.annotation;import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** @program: wys-service* @description: 自定义json解析注解 工具类 * 此文章链接: [复杂json解析] https://blog.csdn.net/wuyuanshun/article/details/128498372* @author: wuyuanshn* @create: 2022-12-26 18:38**/
@Slf4j
public class JsonAnalysisPropertyConfig {public static final ObjectMapper mapper = new ObjectMapper();static Pattern GROUP_INDEX_PATTERN = Pattern.compile("\"([\\u4E00-\\u9FA5A-Za-z0-9_]+)\"[ ]*:[ ]*\"([\\u4E00-\\u9FA5A-Za-z0-9_%&',,+!@#^*《》【】\\-()。;=?$\\x22]+)\"");/*** 根据注解解析 对象中的所有** @param t* @param json* @param <T>*/public static <T> void setObjectByJsonAnalysis(T t, String json) {List<Field> fieldList = getFieldList(t.getClass());for (Field field : fieldList) {setAnalysisProperty(field, t, json);}}/*** 解析对象** @return*/public static List<Field> getFieldList(Class<?> clazz) {List<Field> fieldList = new ArrayList<>();while (clazz != null) {fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));clazz = clazz.getSuperclass();}Field[] fields = new Field[fieldList.size()];fieldList.toArray(fields);return fieldList;}/*** 根据注解解析 对象中的单个字段** @param field* @param t* @param json* @param <T>*/public static <T> void setAnalysisProperty(Field field, T t, String json) {try {JsonAnalysisProperty annotation = field.getAnnotation(JsonAnalysisProperty.class);if (annotation == null || StringUtils.isEmpty(json)) {return;}//一、 验证参数//忽略boolean ignore = annotation.ignore();String split = annotation.split();String splitArray = annotation.splitArray();String selectArrayOne = annotation.selectArrayOne();String defaultValue = annotation.defaultValue();if (ignore) {return;}field.setAccessible(true);//字段内容Object fieldValue = field.get(t);//有默认值 先这设置默认值 防止后续报错 设置不上(字段没有内容的情况下 再设置默认值)if (!StringUtils.isEmpty(defaultValue) && StringUtils.isEmpty(fieldValue)) {setField(field, t, defaultValue);}//默认-核心字段String codeValue = annotation.value();if (StringUtils.isEmpty(codeValue)) {return;}//二、 处理数据JsonNode jsonNode = mapper.readTree(json);String[] codeValueList = codeValue.split(split);for (int i = 0; i < codeValueList.length; i++) {String codeValueItem = codeValueList[i];if (StringUtils.isEmpty(codeValueItem)) {continue;}//剔除多余空格codeValueItem = codeValueItem.trim();//判断是否是数组 是则处理数组 选择节点JsonNode jsonNodeItem = analysisSplitArrayMax(jsonNode, codeValueItem, splitArray, selectArrayOne);//是选择数组 跳过if (jsonNodeItem != null) {jsonNode = jsonNodeItem;continue;}jsonNode = jsonNode.get(codeValueItem);}String text = jsonNode.asText();//设置值
//            field.set(t, text);setField(field, t, text);//如果为空 且有默认值 设置默认值if (StringUtils.isEmpty(text) && !StringUtils.isEmpty(defaultValue) && StringUtils.isEmpty(fieldValue)) {setField(field, t, defaultValue);}} catch (Exception e) {String error = null;try {StackTraceElement[] stackTrace = e.getStackTrace();StackTraceElement stackTraceElement = stackTrace[0];error = e + "\r\n " + stackTraceElement;} catch (Exception exception) {log.error("JsonAnalysisPropertyConfig setAnalysisProperty exception error {}", e, exception);}log.error("JsonAnalysisPropertyConfig setAnalysisProperty field {}  error {}", field, error);}}/*** 设置字段值 不同类型** @param field* @param t* @param value* @param <T>*/public static <T> void setField(Field field, T t, String value) {try {Object obj = value;Class<?> type = field.getType();if (type.equals(String.class)) {
//                field.set(t, obj);} else if (type.equals(Long.class)) {obj = Long.parseLong(value);} else if (type.equals(Integer.class)) {obj = Integer.parseInt(value);} else if (type.equals(Boolean.class)) {obj = Boolean.parseBoolean(value);} else if (type.equals(BigDecimal.class)) {obj = new BigDecimal(value);} else if (type.equals(Double.class)) {obj = Double.parseDouble(value);} else if (type.equals(Float.class)) {obj = Float.parseFloat(value);}
//            else if (type.equals(Date.class)) {
//                obj = DateUtils.getDate(value);
//            }//其他类型可以在这里添加field.set(t, obj);} catch (Exception e) {log.error("JsonAnalysisPropertyConfig setField 赋值字段失败 field {}; t {}; value {}", field, t, value, e);}}/*** 判断是否是数组,如果是 接着处理** @param jsonNode* @param codeValueItem* @param splitArray*/public static JsonNode analysisSplitArray1(JsonNode jsonNode, String codeValueItem, String splitArray) {//判断是否是数组if (codeValueItem.startsWith(splitArray)) {String key;String value;//查看是否需要选择json数组中的某一个Matcher matcher = GROUP_INDEX_PATTERN.matcher(codeValueItem);if (matcher.find()) {key = matcher.group(1);value = matcher.group(2);} else {return null;}Iterator<JsonNode> elements = jsonNode.elements();//遍历找出对应的数组itemwhile (elements.hasNext()) {JsonNode next = elements.next();String getValue = next.get(key).asText();if (!StringUtils.isEmpty(getValue) && getValue.equals(value)) {return next;}}}return null;}/*** 判断是否是数组,如果是 接着处理** @param jsonNode* @param codeValueItem* @param splitArray*/public static JsonNode analysisSplitArray2(JsonNode jsonNode, String codeValueItem, String splitArray) {//判断是否是数组if (codeValueItem.contains(splitArray)) {String[] keyList = null;keyList = codeValueItem.split(splitArray);//一、平级选择String codeNext = keyList[0];jsonNode = jsonNode.get(codeNext);//二、数组选择Iterator<JsonNode> elements = jsonNode.elements();String key;String value;//查看是否需要选择json数组中的某一个Matcher matcher = GROUP_INDEX_PATTERN.matcher(codeValueItem);if (matcher.find()) {key = matcher.group(1);value = matcher.group(2);} else {//匹配不到筛选key value 但是包含数组 按第一哥个返回(认为数组中只有一个JsonNode 或者取第一个【顺序保证的前提下】)if (elements.hasNext()) {return elements.next();}//取不到数据 认为不是数组return null;}//遍历找出对应的数组itemwhile (elements.hasNext()) {JsonNode next = elements.next();//判断是否需要深层选择if (keyList.length > 2) {for (int i = 0; i < keyList.length; i++) {//跳过最后一个 认为最后一个是key value//跳过第一个 第一个事平级选择if (i == 0 || i == keyList.length - 1) {continue;}next = next.get(keyList[i]);}}String getValue = next.get(key).asText();if (!StringUtils.isEmpty(getValue) && getValue.equals(value)) {return next;}}}return null;}/*** 判断是否是数组,如果是 接着处理** @param jsonNode* @param codeValueItem* @param splitArray* @param selectArrayOne*/public static JsonNode analysisSplitArrayMax(JsonNode jsonNode, String codeValueItem, String splitArray, String selectArrayOne) {//判断是否是数组if (codeValueItem.contains(splitArray)) {String[] keyList = null;keyList = codeValueItem.split(splitArray);//一、层级选择String codeNext = keyList[0];jsonNode = jsonNode.get(codeNext);//二、数组选择Iterator<JsonNode> elements = jsonNode.elements();String key;String value;//查看是否需要选择json数组中的某一个Matcher matcher = GROUP_INDEX_PATTERN.matcher(codeValueItem);if (matcher.find()) {key = matcher.group(1);value = matcher.group(2);} else {//匹配不到筛选key value 但是包含数组 按第一个返回(认为数组中只有一个JsonNode 或者取第一个【顺序保证的前提下】)if (elements.hasNext()) {return elements.next();}//取不到数据 认为不是数组return null;}//遍历找出对应的数组itemwhile (elements.hasNext()) {JsonNode next = elements.next();JsonNode returnNext = null;//判断是否需要深层选择if (keyList.length > 2) {for (int i = 0; i < keyList.length; i++) {//跳过最后一个 认为最后一个是key value//跳过第一个 第一个事平级选择if (i == 0 || i == keyList.length - 1) {continue;}String keyItem = keyList[i];if (keyItem.startsWith(selectArrayOne)) {keyItem = keyItem.replace(selectArrayOne, "");returnNext = next;}next = next.get(keyItem);}}String getValue = next.get(key).asText();if (!StringUtils.isEmpty(getValue) && getValue.equals(value)) {//是否选择返回层级if (returnNext != null) {return returnNext;}return next;}}}return null;}public static void main(String[] args) {String a = "aasddd@@\"key_\" :\"value值(asdd,。a)\"";Matcher matcher = GROUP_INDEX_PATTERN.matcher(a);if (matcher.find()) {String key = matcher.group(1);String value = matcher.group(2);System.out.println("key = " + key);System.out.println("value = " + value);/*   key = key_value = value值(asdd,。a)*/}String json = "{\n" +"\"name\": \"wuyuanshun\",\n" +"\"sex\":\"男\",\n" +"\"like\":{\n" +"\t\"title\":\"羽毛球\",\n" +"\t\"level\":1,\n" +"\t\"time\":1672402865000\n" +"},\n" +" \"examination_results\":[\n" +"    {\n" +"\t\"subject\":\"语文\",\n" +"\t\"date\":\"2023-01-29\",\n" +"\t\"score\":98.5\n" +"    }, {\n" +"\t\"subject\":\"数学\",\n" +"\t\"date\":\"2023-01-29\",\n" +"\t\"score\":98.5\n" +"    }, {\n" +"\t\"subject\":\"英语\",\n" +"\t\"date\":\"2023-01-29\",\n" +"\t\"score\":98.5\n" +"    }\n" +"]\n" +"}";Bean bean = new Bean();setObjectByJsonAnalysis(bean,json);System.out.println(bean);}
}

3.如果业务中json的key出现了 > 这种特殊符合(并且前后带空格的)可以替换。如下:

@JsonAnalysisProperty(defaultValue = "0",value = "purchase_crowd > interact_data >> * index_value >> \"index_display\":\"有互动人数\" > show_list >> \"display\":\"首购人数占比\" > value > value")@ApiModelProperty("成交人群分析-有互动人数-首购人数占比") private String purchaseCrowdInteractDataPeopleNumberFirstPurchaseRatio;
//替换为
@JsonAnalysisProperty(split = " 》 ", splitArray = " 》》 ",  selectArrayOne= "** ", defaultValue = "0",value = "purchase_crowd 》 interact_data 》》 ** index_value 》》 \"index_display\":\"有互动人数\" > show_list 》》 \"display\":\"首购人数占比\" 》 value 》 value")@ApiModelProperty("成交人群分析-有互动人数-首购人数占比") private String purchaseCrowdInteractDataPeopleNumberFirstPurchaseRatio;

七、实战 某个业务场景的一段json

{"purchase_crowd":{"interact_data":[{"index_value":{"index_display":"有互动人数","index_name":"","value":{"value":44,"unit":"number"},"change_value":{"value":0.4943820224719101,"unit":"ratio"}},"show_list":[{"display":"粉丝占比","name":"","value":{"value":0.8636363636363636,"unit":"ratio"}},{"display":"首购人数占比","name":"","value":{"value":0.5909090909090909,"unit":"ratio"}}]},{"index_value":{"index_display":"无互动人数","index_name":"","value":{"value":45,"unit":"number"},"change_value":{"value":0.5056179775280899,"unit":"ratio"},},"show_list":[{"display":"粉丝占比","name":"","value":{"value":0.6888888888888889,"unit":"ratio"}},{"display":"首购人数占比","name":"","value":{"value":0.4444444444444444,"unit":"ratio"}}]}]}
}

对应解析java对象

    @JsonAnalysisProperty(defaultValue = "0", value = "purchase_crowd > interact_data >> index_value >> \"index_display\":\"有互动人数\" > value > value")@ApiModelProperty("成交人群分析-有互动人数")private String purchaseCrowdInteractDataPeopleNumberInteracting;@JsonAnalysisProperty(defaultValue = "0", value = "purchase_crowd > interact_data >> index_value >> \"index_display\":\"有互动人数\" > change_value > value")@ApiModelProperty("成交人群分析-有互动人数占比")private String purchaseCrowdInteractDataPeopleNumberRatio;@JsonAnalysisProperty(defaultValue = "0", value = "purchase_crowd > interact_data >> * index_value >> \"index_display\":\"有互动人数\" > show_list >> \"display\":\"粉丝占比\" > value > value")@ApiModelProperty("成交人群分析-有互动人数-粉丝占比")private String purchaseCrowdInteractDataPeopleNumberFansDataRatio;@JsonAnalysisProperty(defaultValue = "0", value = "purchase_crowd > interact_data >> * index_value >> \"index_display\":\"有互动人数\" > show_list >> \"display\":\"首购人数占比\" > value > value")@ApiModelProperty("成交人群分析-有互动人数-首购人数占比")private String purchaseCrowdInteractDataPeopleNumberFirstPurchaseRatio;@JsonAnalysisProperty(defaultValue = "0", value = "purchase_crowd > interact_data >> index_value >> \"index_display\":\"无互动人数\" > value > value")@ApiModelProperty("成交人群分析-无互动人数")private String purchaseCrowdNotInteractDataPeopleNumber;@JsonAnalysisProperty(defaultValue = "0", value = "purchase_crowd > interact_data >> index_value >> \"index_display\":\"无互动人数\" > change_value > value")@ApiModelProperty("成交人群分析-无互动人数占比")private String purchaseCrowdNotInteractDataPeopleNumberRatio;@JsonAnalysisProperty(defaultValue = "0", value = "purchase_crowd > interact_data >> * index_value >> \"index_display\":\"无互动人数\" > show_list >> \"display\":\"粉丝占比\" > value > value")@ApiModelProperty("成交人群分析-无互动人数-粉丝占比")private String purchaseCrowdNotInteractDataPeopleNumberFansDataRatio;@JsonAnalysisProperty(defaultValue = "0", value = "purchase_crowd > interact_data >> * index_value >> \"index_display\":\"无互动人数\" > show_list >> \"display\":\"首购人数占比\" > value > value")@ApiModelProperty("成交人群分析-无互动人数-首购人数占比")private String purchaseCrowdNotInteractDataPeopleNumberFirstPurchaseRatio;

转发请发送私信告知,并标注本文章链接(https://blog.csdn.net/wuyuanshun/article/details/128498372)感谢。

链接: java 自定义json解析注解 复杂json解析 工具类


http://chatgpt.dhexx.cn/article/4tAqfXGf.shtml

相关文章

@JsonSerialize注解的使用

使用场景 在开发中&#xff0c;我们将对象序列化为JSON传输给前端&#xff0c;有时候我们的某个或者某些字段需要特殊处理&#xff0c;比如我们有一个日期字段&#xff0c;我们希望当日期为NULL时给前端不返回NULL而返回为未完成等信息&#xff0c;或者我们有一些状态字段&…

json 文件加注释

根据JSON规范(http://www.json.org, RFC 4627, RFC 7159)&#xff0c;不支持注释。JSON规范之所以不允许加注释&#xff0c;主要是防止&#xff1a;过多的注释&#xff0c;影响了文件本身的数据载体的目的。 但是有些场合&#xff0c;尤其是配置文件&#xff0c;还是希望能够帮…

@JsonProperty注解

序言 JsonProperty 当一个Java对象转换成Json字符串后&#xff0c;如果不是正确的实际名称有可能会出现异常。比如数据库中的坐标名称是x_axis&#xff0c;而定义Java对象是是xAxis&#xff0c;那么这时就需要使用到JsonProperty注解&#xff0c;并且配合ObjectMapper.writeVa…

@JsonProperty注解解析

1. 概述 来源: JsonPrpperty是jackson包下的一个注解&#xff0c;详细路径(com.fasterxml.jackson.annotation.JsonProperty;)作用:JsonProperty用在属性上&#xff0c;将属性名称序列化为另一个名称。例子&#xff1a;public class Person{JsonProperty(value "name&qu…

json文件怎么写注释

1、 使用编辑器打开json文件&#xff0c;现在是没有注释内容的。 &#xff08;如果没有的话需要下载安装&#xff09; 2、一个json文件&#xff0c;其实就是一个js脚本文件&#xff0c;我们可以使用//的单行注释符。 3、也可以使用/* */符号来支持多行注释 4、我们可以使用重…

vscode对json加注释

vscode对json加注释 问题呈现&#xff1a;comments are not permitted in JSON 解决方案 第一步&#xff1a;点击vscode工具栏底部的json 第二步&#xff1a;在模式中下拉选择JSON with Comments 第三步&#xff1a;验证 原来报错的地方不报错了 点击查看settings.json文件&…

JSON怎样添加注释

今天在写一个程序的时候发现了一个问题&#xff0c;在json文件中添加注释之后&#xff0c;程序就出现bug了 于是&#xff0c;去搜了一下这个问题的相关解释&#xff0c;在这里和大家分享一下&#xff1a; JSON为什么不能添加注释&#xff1f; 这位外国友人给出的解释&…

JSON文件加注释的7种方法

JSON文件加注释的7种方法 缺省不能加注释&#xff0c;现实有需求 根据JSON规范(http://www.json.org, RFC 4627, RFC 7159)&#xff0c;不支持注释。JSON规范之所以不允许加注释&#xff0c;主要是防止&#xff1a;过多的注释&#xff0c;影响了文件本身的数据载体的目的。 …

JSON 注释

文章目录 JSON 注释使用特殊的键名JSON5 JSON 注释 JSON 是一种纯粹的数据交换格式&#xff0c;其简单、灵活的特性使得 JSON 适合被用于各种不同的场景&#xff0c;例如在配置文件中、在接口返回的数据中都会用到 JSON 格式。然而 JSON 却有一个非常明显的缺点&#xff0c;那…

利用相关分析法辨识脉冲响应

主程序: %% 参数初始化 times1; Np63;%2^6-1,输入序列循环周期 N252*times; a1;%输入序列幅值 T01;%采样时间 delta_gzeros(200,1); ratio_vyzeros(200,1); %% 人机对话 sigmainput(请输入噪声标准差: ); rinput(请输入循环周期数(本程序中&#xff0c;输入2或3): ); % sigma…

【控制理论】矩形脉冲响应曲线法 Python 绘图

前言 在过程控制系统的学习中&#xff0c;测量一个被控对象的阶跃响应非常重要&#xff0c;因为根据阶跃响应曲线可以得到被控对象的许多非常重要的参数。而有一个非常重要的测量阶跃响应曲线的方法是矩形脉冲响应曲线法。在学习的过程中&#xff0c;我走了一些弯路&#xff0…

【视频】向量自回归VAR数学原理及R软件经济数据脉冲响应分析实例

最近我们被客户要求撰写关于向量自回归VAR的研究报告&#xff0c;包括一些图形和统计输出。 向量自回归 (VAR) 是一种用于多变量时间序列分析的统计模型&#xff0c;尤其是在变量具有相互影响关系的时间序列中&#xff0c;本视频中我们介绍了向量自回归并在R软件中进行实现。…

用脉冲响应不变法设计IIR 滤波器 MATLAB实现

一、实验目的 1&#xff0e; 掌握脉冲响应不变法设计IIR 数字滤波器的原理及具体设计方法。 2&#xff0e; 观察用脉冲响应不变法设计的滤波器的时域特性和频域特性&#xff0c;比较所设计的数 字滤波器的和相应模拟滤波器的频域特性&#xff0c;观察脉冲响应不变法设计中产生的…

非参数模型辨识:脉冲响应曲线

1.1 问题描述 1.2 方法思路 首先根据系统脉冲响应函数G(t)计算出51(0-50)个真值数据G,再利用以下公式产生550组带噪声的仿真数据。 最后利用上述仿真矩阵构造相应的数据矩阵&#xff0c;再用最小二乘法求解系统的脉冲响应估计值&#xff0c;其构造公式如下所示。 1.3 实验…

R语言VAR模型的不同类型的脉冲响应分析

目录 模型与数据 估算值 预测误差脉冲响应 识别问题 正交脉冲响应 结构脉冲反应 广义脉冲响应 参考文献 最近我们被客户要求撰写关于脉冲响应分析的研究报告&#xff0c;包括一些图形和统计输出。脉冲响应分析是采用向量自回归模型的计量经济学分析中的重要一步。它们的…

R语言用向量自回归(VAR)进行经济数据脉冲响应研究分析

自从Sims&#xff08;1980&#xff09;发表开创性的论文以来&#xff0c;向量自回归模型已经成为宏观经济研究中的关键工具。最近我们被客户要求撰写关于向量自回归&#xff08;VAR&#xff09;的研究报告&#xff0c;包括一些图形和统计输出。这篇文章介绍了VAR分析的基本概念…

matlab单位阶跃响应与单位脉冲响应,python 已知响应函数求单位阶跃响应或脉冲响应...

最近学习自动控制原理,关于控制系统的一些,老师用布置了一些作业说要用matlab画,我试试python 首先介绍一下所使用的库:control matplotlib sympy 1.control库:用来计算脉冲响应与阶跃响应 Paste_Image.png 2.sympy:用以化简多项式为和的形式方便写参数 比如我们使用 sym…

使用扫频信号测量房间脉冲响应

使用指数扫频正弦信号&#xff0c;信号生成方法如下&#xff1a; 其中: &#xff0c;是扫频信号的起始频率和结束频率 是扫频信号的时长 是扫频率 逆信号是通过缩放时间翻转的信号计算&#xff0c;计算方法如下&#xff1a; 其中 信号的脉冲响应 扫频信号、逆信号、IR&#xf…

matlab一直系统函数画脉冲响应,【 MATLAB 】使用 impz 函数计算并画出脉冲响应

这篇博文在于讨论 impz 函数的使用。 我在 MATLAB 中查看 impz 的帮助文档时,始终看的不是太明白这个函数的使用,于是我根据一个例子,对这个函数做了一点分析,解决了一些我的疑惑,记录于此。 帮助文档上对这个函数的概括是数字滤波器的脉冲响应。 所谓的数字滤波器不就是一…

相关分析法辨识系统脉冲响应

背景介绍 在实际工程中&#xff0c;由于系统的测量都是载噪的&#xff0c;而且噪声对观测数据的影响常常达到不可忽略的地步&#xff0c;因此当噪声影响足以使得要求的精度不足时&#xff0c;就必须考虑噪声的影响。实际中&#xff0c;系统噪声存在各种难以精确描述的因素&…