@JsonProperty注解

article/2025/11/10 13:54:50

序言

@JsonProperty

当一个Java对象转换成Json字符串后,如果不是正确的实际名称有可能会出现异常。比如数据库中的坐标名称是x_axis,而定义Java对象是是xAxis,那么这时就需要使用到@JsonProperty注解,并且配合ObjectMapper.writeValueAsString方法使用去序列化对象成字符串。如下示例demo,

@JsonProperty(value = "", index = 1, access = JsonProperty.Access.xxx)

其中value为成员变量真实名称,index为序列化之后所展示的顺序,access为该对象的访问控制权限。

@Slf4j
public class JsonPropertyDemo {@Data@AllArgsConstructor@NoArgsConstructor@Builder@ToStringprivate static class Coordinate {@JsonProperty(value = "x_axis", index = 1, access = JsonProperty.Access.WRITE_ONLY)private String xAxis;@JsonProperty(value = "y_axis", index = 2, access = JsonProperty.Access.READ_WRITE)private String yAxis;@JsonProperty(value = "z_axis", index = 3, access = JsonProperty.Access.READ_WRITE)private String zAxis;}public static void main(String[] args) {Coordinate coordinate = Coordinate.builder().xAxis("113.58").yAxis("37.86").zAxis("40.05").build();String jsonStr = JSON.toJSONString(coordinate);log.info("serializes the specified object into its equivalent Json representation :" + jsonStr);ObjectMapper mapper = new ObjectMapper();try {String str = mapper.writeValueAsString(coordinate);log.info("serialize any Java value as a String : " + str);Object bean = mapper.readerFor(Coordinate.class).readValue(str);log.info("read or update instances of specified type : " + bean);} catch (JsonProcessingException e) {log.error("error message : " + e);}}
}

注解一般都是通过反射拿到对映的成员变量然后再进行增强,@JsonProperty把成员变量序列化成另外一个名称,并且它在序列化和反序列化的过程中都是使用的实际名称。

@JsonAlias

com.fasterxml.jackson.annotation中的@JsonProperty是可以在序列化和反序列化中使用,而@JsonAlias只在反序列化中起作用,指定Java属性可以接受的更多名称。文末链接也有JsonAlias的实例源码,下面就简单举一个例子,

@Slf4j
public class JsonAliasDemo {@Data@AllArgsConstructor@NoArgsConstructor@Builder@ToStringprivate static class Coordinate {@JsonAlias(value = "x_location")@JsonProperty(value = "x_axis")private String xAxis;@JsonProperty(value = "y_axis")@JsonAlias(value = "y_location")private String yAxis;@JsonProperty(value = "z_axis")@JsonAlias(value = "z_location")private String zAxis;}public static void main(String[] args) {String location = "{\"x_location\":\"113.58\",\"y_location\":\"37.86\",\"z_location\":\"40.05\"}";ObjectMapper mapper = new ObjectMapper();try {Object bean = mapper.readValue(location, Coordinate.class);log.info("read or update instances of specified type : " + bean);} catch (JsonProcessingException e) {log.error("error message : " + e);}}
}

@JsonAlias里的别名的json字符串,在反序列化时可以识别出来,不会反序列化失败,结果如下图,

@JsonProperty源码

JsonProperty的源码是一个注解类,注解类上的几个元注解就不解释了,可以参考文末链接7,该注解的主要作用就是在pojo属性上执行自定义处理器流程。

@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonProperty {String USE_DEFAULT_NAME = "";int INDEX_UNKNOWN = -1;String value() default "";boolean required() default false;int index() default -1;String defaultValue() default "";JsonProperty.Access access() default JsonProperty.Access.AUTO;public static enum Access {AUTO,READ_ONLY,WRITE_ONLY,READ_WRITE;private Access() {}}
}

那么下面就看一下处理器流程做了一些什么事,找到JacksonAnnotationIntrospector类,

先看在jackson 2.6版本之后找到添加了@JsonProperty注解的pojo属性做了什么事,注意这里是一个过期的旧方法,保留是为了兼容使用老版本jackson的方法(@Deprecated注解)。首先该方法通过反射拿到成员变量,然后再获取注解中的属性值(eg:@JsonProperty(value = "x_axis")),如果找到则返回value值,否则就返回原成员变量的name。

    /*** Since 2.6, we have supported use of {@link JsonProperty} for specifying* explicit serialized name*/@Override@Deprecated // since 2.8public String findEnumValue(Enum<?> value){// 11-Jun-2015, tatu: As per [databind#677], need to allow explicit naming.//   Unfortunately cannot quite use standard AnnotatedClass here (due to various//   reasons, including odd representation JVM uses); has to do for nowtry {// We know that values are actually static fields with matching name so:Field f = value.getClass().getField(value.name());if (f != null) {JsonProperty prop = f.getAnnotation(JsonProperty.class);if (prop != null) {String n = prop.value();if (n != null && !n.isEmpty()) {return n;}}}} catch (SecurityException e) {// 17-Sep-2015, tatu: Anything we could/should do here?} catch (NoSuchFieldException e) {// 17-Sep-2015, tatu: should not really happen. But... can we do anything?}return value.name();}

下面再看一下jackson2.7之后是怎么做的,首先该方法不是根据成员变量的name获取类的属性,而是直接遍历类中所有的属性,然后用哈希表expl存属性的name和注解中的value映射关系,然后一次性遍历一遍把所有的属性的真实值集合返回出来(如果没有配置@JsonProperty的value则是属性原值,如果配有@JsonProperty的value则返回value值),这么做的好处在于不用一次一次的解析真实属性值而是一起解析真实属性值。

@Override // since 2.7public String[] findEnumValues(Class<?> enumType, Enum<?>[] enumValues, String[] names) {HashMap<String,String> expl = null;for (Field f : ClassUtil.getDeclaredFields(enumType)) {if (!f.isEnumConstant()) {continue;}JsonProperty prop = f.getAnnotation(JsonProperty.class);if (prop == null) {continue;}String n = prop.value();if (n.isEmpty()) {continue;}if (expl == null) {expl = new HashMap<String,String>();}expl.put(f.getName(), n);}// and then stitch them together if and as necessaryif (expl != null) {for (int i = 0, end = enumValues.length; i < end; ++i) {String defName = enumValues[i].name();String explValue = expl.get(defName);if (explValue != null) {names[i] = explValue;}}}return names;}

其他属性的解析也基本上如出一辙,代码如下,

    @Overridepublic Boolean hasRequiredMarker(AnnotatedMember m){JsonProperty ann = _findAnnotation(m, JsonProperty.class);if (ann != null) {return ann.required();}return null;}@Overridepublic JsonProperty.Access findPropertyAccess(Annotated m) {JsonProperty ann = _findAnnotation(m, JsonProperty.class);if (ann != null) {return ann.access();}return null;}@Overridepublic Integer findPropertyIndex(Annotated ann) {JsonProperty prop = _findAnnotation(ann, JsonProperty.class);if (prop != null) {int ix = prop.index();if (ix != JsonProperty.INDEX_UNKNOWN) {return Integer.valueOf(ix);}}return null;}@Overridepublic String findPropertyDefaultValue(Annotated ann) {JsonProperty prop = _findAnnotation(ann, JsonProperty.class);if (prop == null) {return null;}String str = prop.defaultValue();// Since annotations do not allow nulls, need to assume empty means "none"return str.isEmpty() ? null : str;}

序列化和反序列化配置

另外,序列化和反序列化中会有些常见配置,比如常见的如下,

DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES

在反序列化json字符串成Java对象时,遇到未知属性是否抛出异常信息。

@Slf4j
public class DeserializationFeatureDemo {/*** 注意上面的实例对象必须要有无参构造函数,否则在反序列化时创建实例对象* 会抛出异常com.fasterxml.jackson.databind.exc.InvalidDefinitionException*/@Data@Builder@AllArgsConstructor@NoArgsConstructorprivate static class Person {private String name;private Long age;}public static void main(String[] args) {String jsonStr = "{\"name\":\"张三\",\"age\":18,\"sex\":\"男\"}";System.out.println("serialize java object to json : " + jsonStr);Person A = parse(jsonStr, Person.class, false);System.out.println("after deserialize to object :" + JSON.toJSONString(A));Person B = parse(jsonStr, Person.class, true);System.out.println("after deserialize to object :" + JSON.toJSONString(B));}private static <T> T parse(String json, Class<T> tClass, boolean failOnUnknownProperties) {ObjectMapper objectMapper = new ObjectMapper();objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, failOnUnknownProperties);T result = null;try {result = objectMapper.readValue(json, tClass);} catch (JsonProcessingException e) {log.error("Failed to deserialize JSON content, json value : " + json);}return result;}
}

可以看到输出结果,配置设为true时在反序列化未知属性直接抛出异常信息,

 JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS

是否允许JSON字符串包含非引号控制字符(值小于32的ASCII字符,包含制表符和换行符)。 由于JSON规范要求对所有控制字符使用引号,这是一个非标准的特性,因此默认禁用。

更多配置参考文末链接6。

参考链接:

1、JSON在线 | JSON解析格式化—SO JSON在线工具

2、JsonProperty (Jackson JSON Processor)

3、Java类com.fasterxml.jackson.annotation.JsonProperty的实例源码 - 编程字典

4、Java类com.fasterxml.jackson.annotation.JsonAlias的实例源码 - 编程字典

5、Jackson data binding - 知乎

6、4. JSON字符串是如何被解析的?JsonParser了解一下(中)-阿里云开发者社区

7、注解的使用_四问四不知的博客-CSDN博客


http://chatgpt.dhexx.cn/article/mqMUsbXK.shtml

相关文章

@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;系统噪声存在各种难以精确描述的因素&…

脉冲响应

使用MATLAB中的系统建模工具对热风枪Chirp激励和输出数据建立三阶模型&#xff0c;并输出该模型的离散系统传递函数&#xff1a;tf2 。 基于Chirp信号激励下系统数据数据建模响应曲线 在MATLAB中显示 tf2 的数据。可以得到该离散时间系统函数有理多项式对应的分子和分母的系…

使用Stata做脉冲响应分析

Source: Rizaudin Sahlan → Impulse Response Function with Stata (time series) 在这篇推文中&#xff0c;我们讨论 VAR 模型中的脉冲响应函数(IRFs)。 脉冲响应函数反映了当 VAR 模型某个变量受到"外生冲击"时&#xff0c;模型中其他变量受到的动态影响。我们会…

matlab 单位脉冲响应,滤波器系数、单位脉冲响应、频率响应等概念笔记

单位脉冲响应&#xff1a;单位脉冲和滤波器系数的卷积。 对于FIR滤波器来说&#xff0c;单位脉冲响应就是滤波器系数。对于IIR滤波器&#xff0c;应该是需要用matlab中的filter函数&#xff0c;得到单位脉冲响应。 频率响应&#xff1a;幅度和相位随频率的变化关系。具体地&…