From 38c82d16bd04349dd917b62ee92b4806c4334a36 Mon Sep 17 00:00:00 2001 From: Kevin Binswanger Date: Mon, 26 Oct 2020 15:32:42 -0500 Subject: [PATCH 1/2] Adds `@JsonKey` annotation. This annotation will be used like `@JsonValue` but only when serializing Map keys. See jackson-databind/#2871 --- .../fasterxml/jackson/annotation/JsonKey.java | 60 +++++++++++++++++++ .../jackson/annotation/JsonValue.java | 5 ++ 2 files changed, 65 insertions(+) create mode 100644 src/main/java/com/fasterxml/jackson/annotation/JsonKey.java diff --git a/src/main/java/com/fasterxml/jackson/annotation/JsonKey.java b/src/main/java/com/fasterxml/jackson/annotation/JsonKey.java new file mode 100644 index 00000000..b7e260f0 --- /dev/null +++ b/src/main/java/com/fasterxml/jackson/annotation/JsonKey.java @@ -0,0 +1,60 @@ +package com.fasterxml.jackson.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation + * that indicates that the value of annotated accessor (either field + * or "getter" method [a method with non-void return type, no args]) + * is to be used as the single value to serialize for the instance. + * This value will be used only if the instance is being serialized + * as a key in a Map type. + * Usually value will be of a simple scalar type + * (String or Number), but it can be any serializable type (Collection, + * Map or Bean). + *

+ * At most one accessor of a Class can be annotated with this annotation; + * if more than one is found, an exception may be thrown. + * Also, if method signature of annotated method is not compatible with Getters, + * an exception may be thrown (whether exception is thrown or not is an + * implementation detail (due to filtering during introspection, some annotations + * may be skipped) and applications should not rely on specific behavior). + *

+ * A typical usage is that of annotating toString() + * method so that returned String value is used as the JSON serialization; + * and if deserialization is needed, there is matching constructor + * or factory method annotated with {@link JsonCreator} annotation. + *

+ * Boolean argument is only used so that sub-classes can "disable" + * annotation if necessary. + *

+ * NOTE: when use for Java enums, one additional feature is + * that value returned by annotated method is also considered to be the + * value to deserialize from, not just JSON String to serialize as. + * This is possible since set of Enum values is constant and it is possible + * to define mapping, but can not be done in general for POJO types; as such, + * this is not used for POJO deserialization. + * + * @see JsonCreator + * @see JsonValue + */ +@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, + ElementType.FIELD +}) +@Retention(RetentionPolicy.RUNTIME) +@JacksonAnnotation +public @interface JsonKey +{ + /** + * Optional argument that defines whether this annotation is active + * or not. The only use for value 'false' if for overriding purposes. + * Overriding may be necessary when used + * with "mix-in annotations" (aka "annotation overrides"). + * For most cases, however, default value of "true" is just fine + * and should be omitted. + */ + boolean value() default true; +} \ No newline at end of file diff --git a/src/main/java/com/fasterxml/jackson/annotation/JsonValue.java b/src/main/java/com/fasterxml/jackson/annotation/JsonValue.java index d78231bc..0b7d710f 100644 --- a/src/main/java/com/fasterxml/jackson/annotation/JsonValue.java +++ b/src/main/java/com/fasterxml/jackson/annotation/JsonValue.java @@ -36,8 +36,13 @@ * This is possible since set of Enum values is constant and it is possible * to define mapping, but can not be done in general for POJO types; as such, * this is not used for POJO deserialization. + *

+ * NOTE: When the instance is being serialized as the key of a Map type, + * this will be ignored if an accessor is annotated with + * {@link JsonKey}. * * @see JsonCreator + * @see JsonKey */ @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD // since 2.9 From 01293809d23a3b954971209736338e59e0ed081e Mon Sep 17 00:00:00 2001 From: Kevin Binswanger Date: Wed, 28 Oct 2020 15:38:42 -0500 Subject: [PATCH 2/2] Removes some incorrect Javadoc This stuff was copied from JsonValue and isn't correct here. --- .../java/com/fasterxml/jackson/annotation/JsonKey.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/annotation/JsonKey.java b/src/main/java/com/fasterxml/jackson/annotation/JsonKey.java index b7e260f0..138414b3 100644 --- a/src/main/java/com/fasterxml/jackson/annotation/JsonKey.java +++ b/src/main/java/com/fasterxml/jackson/annotation/JsonKey.java @@ -30,15 +30,7 @@ *

* Boolean argument is only used so that sub-classes can "disable" * annotation if necessary. - *

- * NOTE: when use for Java enums, one additional feature is - * that value returned by annotated method is also considered to be the - * value to deserialize from, not just JSON String to serialize as. - * This is possible since set of Enum values is constant and it is possible - * to define mapping, but can not be done in general for POJO types; as such, - * this is not used for POJO deserialization. * - * @see JsonCreator * @see JsonValue */ @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD,