简体   繁体   English

使用Jackson对序列化的最终类进行反序列化

[英]Deserialization of serialized final class using Jackson

I have following value holder class for users: 我为用户提供了以下值持有者类:

package entities;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.immutables.value.Value;

import javax.annotation.Nullable;

@Value.Immutable
@JsonSerialize(as = ImmutableUser.class)
@JsonDeserialize(as = ImmutableUser.class)
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
public interface User {

    String getUsername();
    String getEmail();
    @Nullable String getPassword();
    @Nullable String getEncodedPassword();
}

Immutable final implementation of this value holder is being generated during compilation: 在编译过程中将生成此值持有者的不变最终实现:

@SuppressWarnings("all")
@ParametersAreNonnullByDefault
@Generated({"Immutables.generator", "User"})
@Immutable
public final class ImmutableUser implements User {

Serialized instance of Immutable 不可变的序列化实例

{"@class":"entities.ImmutableUser$Json","username":"testuser","email":"123@gmail.com","password":null,"encodedPassword":null}

The problem is that deserialization of this JSON fails with following error: 问题是此JSON的反序列化失败,并显示以下错误:

java.lang.IllegalArgumentException: Class entities.ImmutableUser$Json is not assignable to entities.User
    at com.fasterxml.jackson.databind.JavaType._assertSubclass(JavaType.java:466)
    at com.fasterxml.jackson.databind.JavaType.narrowBy(JavaType.java:149)
    at com.fasterxml.jackson.databind.type.TypeFactory.constructSpecializedType(TypeFactory.java:315)
    at com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver._typeFromId(ClassNameIdResolver.java:64)
    ... 38 more

Why does @class property in JSON for serialized instance have value "entities.ImmutableUser$Json" instead of "entities.ImmutableUser" ? 为什么序列化实例的JSON中的@class属性具有值"entities.ImmutableUser$Json"而不是"entities.ImmutableUser" Is it because of fact that the class is final ? 难道是因为事实上班是final吗? Is there any other way to serialize such classes and to avoid problems during deserialization? 还有其他方法可以序列化此类并避免反序列化过程中的问题吗?

Found out that the problem was caused by generated class. 发现问题是由生成的类引起的。 Turns out that such classes should be marshaled using specific classes: immutables.github.io/site1.x/json.html 事实证明,此类类应使用特定的类进行编组:immutables.github.io/site1.x/json.html

The http://immutables.github.io/site1.x/json.html is referring to the older version of documentation and is quite irrelevant if you use Immutables v2.0 and up. http://immutables.github.io/site1.x/json.html指的是较旧版本的文档,如果您使用Immutables v2.0及更高版本,则该文档不相关。 In your case you're facing an already fixed issue (similar to https://github.com/immutables/immutables/issues/175 ). 就您而言,您已经面临一个已解决的问题(类似于https://github.com/immutables/immutables/issues/175 )。 Try upgrading to Immutables v2.1 to get it resolved. 尝试升级到Immutables v2.1以解决该问题。

In nutshell, Jackson have feature annotation @JsonValue to substitute object during serialization. 简而言之,Jackson具有功能注释@JsonValue以在序列化期间替换对象。 Unfortunately as we found out that it does not play well with other functionality as @JsonTypeInfo and @JsonSubTypes . 不幸的是,正如我们发现的那样,它无法与@JsonTypeInfo@JsonSubTypes等其他功能@JsonSubTypes See https://github.com/FasterXML/jackson-databind/issues/937 . 参见https://github.com/FasterXML/jackson-databind/issues/937

Version 2.1 of Immutables no longer used @JsonValue , so it should work now. 不可变的 2.1版不再使用@JsonValue ,因此它现在应该可以使用。 If not, please report it as a bug to https://github.com/immutables/immutables/issues 如果不是,请将其作为错误报告给https://github.com/immutables/immutables/issues

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM