jackson反序列化器获取类型

简介: jackson反序列化器获取类型

不要用陌生人的目光来看你所爱的人,也不要认为自己做出了牺牲——贝·列昂尼多娃

例如这里使用hutoolEnumUtil.getEnumAt传入枚举的ordinal,以及枚举类型,获取到具体的枚举常量值

import cn.hutool.core.util.EnumUtil;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import java.io.IOException;
/**
 * @author VampireAchao
 * @since 2023/1/12 15:46
 */
public class EnumOrdinalDeSerializer<E extends Enum<E>> extends JsonDeserializer<E> implements ContextualDeserializer {
    private JavaType type;
    public EnumOrdinalDeSerializer() {
    }
    public EnumOrdinalDeSerializer(JavaType type) {
        this.type = type;
    }
    /**
     * Method that can be called to ask implementation to deserialize
     * JSON content into the value type this serializer handles.
     * Returned instance is to be constructed by method itself.
     * <p>
     * Pre-condition for this method is that the parser points to the
     * first event that is part of value to deserializer (and which
     * is never JSON 'null' literal, more on this below): for simple
     * types it may be the only value; and for structured types the
     * Object start marker or a FIELD_NAME.
     * </p>
     * <p>
     * The two possible input conditions for structured types result
     * from polymorphism via fields. In the ordinary case, Jackson
     * calls this method when it has encountered an OBJECT_START,
     * and the method implementation must advance to the next token to
     * see the first field name. If the application configures
     * polymorphism via a field, then the object looks like the following.
     * <pre>
     *      {
     *          "@class": "class name",
     *          ...
     *      }
     *  </pre>
     * Jackson consumes the two tokens (the <tt>@class</tt> field name
     * and its value) in order to learn the class and select the deserializer.
     * Thus, the stream is pointing to the FIELD_NAME for the first field
     * after the @class. Thus, if you want your method to work correctly
     * both with and without polymorphism, you must begin your method with:
     * <pre>
     *       if (p.currentToken() == JsonToken.START_OBJECT) {
     *         p.nextToken();
     *       }
     *  </pre>
     * This results in the stream pointing to the field name, so that
     * the two conditions align.
     * <p>
     * Post-condition is that the parser will point to the last
     * event that is part of deserialized value (or in case deserialization
     * fails, event that was not recognized or usable, which may be
     * the same event as the one it pointed to upon call).
     * <p>
     * Note that this method is never called for JSON null literal,
     * and thus deserializers need (and should) not check for it.
     *
     * @param p    Parsed used for reading JSON content
     * @param ctxt Context that can be used to access information about
     *             this deserialization activity.
     * @return Deserialized value
     */
    @Override
    public E deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        return EnumUtil.getEnumAt((Class<E>) type.getRawClass(), p.getValueAsInt());
    }
    /**
     * Method called to see if a different (or differently configured) deserializer
     * is needed to deserialize values of specified property.
     * Note that instance that this method is called on is typically shared one and
     * as a result method should <b>NOT</b> modify this instance but rather construct
     * and return a new instance. This instance should only be returned as-is, in case
     * it is already suitable for use.
     *
     * @param ctxt     Deserialization context to access configuration, additional
     *                 deserializers that may be needed by this deserializer
     * @param property Method, field or constructor parameter that represents the property
     *                 (and is used to assign deserialized value).
     *                 Should be available; but there may be cases where caller cannot provide it and
     *                 null is passed instead (in which case impls usually pass 'this' deserializer as is)
     * @return Deserializer to use for deserializing values of specified property;
     * may be this instance or a new instance.
     * @throws JsonMappingException
     */
    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
        //beanProperty is null when the type to deserialize is the top-level type or a generic type, not a type of a bean property
        JavaType type = ctxt.getContextualType() != null
                ? ctxt.getContextualType()
                : property.getMember().getType();
        return new EnumOrdinalDeSerializer<>(type);
    }
}


使用:

class Entity{
    @JsonDeserialize(using = EnumOrdinalDeSerializer.class)
    private MyEnum myEnum;
}
相关文章
|
15天前
|
XML JSON Java
Jackson反序列化不可变类
Jackson 默认的反序列化策略需要无参构造器和字段 setter 函数。对于不可变类(如 `ImmutableUser`),可以通过以下三种方式解决: 1. **使用 Jackson 注解**:在全参构造器上使用 `@JsonCreator` 和 `@JsonProperty` 注解。 2. **使用 jackson-module-parameter-names**:引入依赖并注册 `ParameterNamesModule` 模块。 3. **使用 Mixins 机制**:创建一个 Mixin 类,使用 `@JsonCreator` 和 `@JsonProperty` 注解
Jackson反序列化不可变类
|
2月前
|
存储 XML JSON
用示例说明序列化和反序列化
用示例说明序列化和反序列化
|
5月前
|
JSON Java API
jackson序列化和反序列化中的注解和扩展点大全【收藏】
jackson序列化和反序列化中的注解和扩展点大全【收藏】
|
6月前
|
JSON Java Maven
使用Jackson进行 JSON 序列化和反序列化
使用Jackson进行 JSON 序列化和反序列化
135 0
|
存储 JSON fastjson
聊聊fastjson反序列化的那些坑
聊聊fastjson反序列化的那些坑
2898 0
聊聊fastjson反序列化的那些坑
|
JSON Java 数据格式
Jackson对象 ObjectMapper实现序列化数据为json
Jackson对象 ObjectMapper实现序列化数据为json
|
Java fastjson
fastJson序列化与反序列化
fastJson序列化与反序列化
|
Java Spring
记一次jackson序列化Boolean的坑
记一次jackson序列化Boolean的坑
529 0
|
JSON 数据格式
JSON - 如何使用 Jackson 处理复杂的反序列化到对象的数据结构
JSON - 如何使用 Jackson 处理复杂的反序列化到对象的数据结构
269 0
|
Java fastjson NoSQL
解决fastjson反序列化时报错的问题
现在JAVA 对象如下: @Data @NoArgsConstructor public class ResourceTreeDto implements Serializable, Comparable { private Coll...
3240 0