Java @JsonTypeInfo未添加"@“类”;包装类时的json id也有@JsonTypeInfo

Java @JsonTypeInfo未添加"@“类”;包装类时的json id也有@JsonTypeInfo,java,json,serialization,jackson,Java,Json,Serialization,Jackson,我试图序列化一个“holder”类,该类中有一个值,其类型派生自泛型。ie“class HasValue”中有一个“private a value” 此外,我还有一个接口“Inf”和一个实现该接口的具体类“InfCls”。该接口用@JsonTypeInfo标记,并被告知创建一个“@class”字段 如果holder类上没有@JsonTypeInfo,那么一切都可以正常工作。但当我加上这句话时,它就断了 注意:虽然在这个实例中我不需要@JsonTypeInfo(因为holder始终是一个具体的类)

我试图序列化一个“holder”类,该类中有一个值,其类型派生自泛型。ie“class HasValue”中有一个“private a value”

此外,我还有一个接口“Inf”和一个实现该接口的具体类“InfCls”。该接口用@JsonTypeInfo标记,并被告知创建一个“@class”字段

如果holder类上没有@JsonTypeInfo,那么一切都可以正常工作。但当我加上这句话时,它就断了

注意:虽然在这个实例中我不需要@JsonTypeInfo(因为holder始终是一个具体的类),但在需要它时也会出现同样的问题,所以我选择这个作为一个更简单的示例

SCWE如下:

import static org.junit.Assert.assertEquals;

import java.util.Objects;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

public class SerializationIssues {

    // No @JsonTypeInfo on HasValue
    @Test
    public void json_HasValue_Inf_javaType() throws Exception {
        HasValue<Inf> object = new HasValue<>(new InfCls(1));

        ObjectMapper objectMapper = new ObjectMapper();
        JavaType javaType = objectMapper.getDeserializationConfig().getTypeFactory().constructParametricType(HasValue.class, Inf.class);
        String serialized = objectMapper.writerFor(javaType).writeValueAsString(object);
        HasValue<?> deserialized = objectMapper.readValue(serialized, javaType);

        assertEquals(object, deserialized);
    }

    // @JsonTypeInfo on HasValueId
    @Test
    public void json_HasValueId_Inf_javaType() throws Exception {
        HasValueId<Inf> object = new HasValueId<>(new InfCls(1));

        ObjectMapper objectMapper = new ObjectMapper();
        JavaType javaType = objectMapper.getDeserializationConfig().getTypeFactory().constructParametricType(HasValueId.class, Inf.class);
        String serialized = objectMapper.writerFor(javaType).writeValueAsString(object);
        HasValueId<?> deserialized = objectMapper.readValue(serialized, javaType);

        assertEquals(object, deserialized);
    }

    // ===== An interface and impl to test @JsonTypeInfo =====
    @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = As.PROPERTY, property = "@class")
    public static interface Inf {
    }

    @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, isGetterVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
    public static class InfCls implements Inf {
        private int val;

        @JsonCreator
        public InfCls(@JsonProperty("val") int val) {
            this.val = val;
        }

        @Override
        public String toString() {
            return "InfCls [val=" + val + "]";
        }

        @Override
        public int hashCode() {
            return 31 * 1 + val;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            InfCls other = (InfCls) obj;
            if (val != other.val)
                return false;
            return true;
        }
    }

    // ===== A class that has a value =====
    @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, isGetterVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
    public static class HasValue<A> {
        private final A val;

        @JsonCreator
        public HasValue(@JsonProperty("val") A val) {
            this.val = Objects.requireNonNull(val);
        }

        public A get() {
            return val;
        }

        @Override
        public String toString() {
            return "HasValue [val=" + val + "]";
        }

        @Override
        public int hashCode() {
            return 31 * 1 + ((val == null) ? 0 : val.hashCode());
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            HasValue<?> other = (HasValue<?>) obj;
            if (val == null) {
                if (other.val != null)
                    return false;
            } else if (!val.equals(other.val))
                return false;
            return true;
        }
    }

    @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
    @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, isGetterVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
    public static class HasValueId<A> {
        private final A val;

        @JsonCreator
        public HasValueId(@JsonProperty("val") A val) {
            this.val = Objects.requireNonNull(val);
        }

        public A get() {
            return val;
        }

        @Override
        public String toString() {
            return "HasValue [val=" + val + "]";
        }

        @Override
        public int hashCode() {
            return 31 * 1 + ((val == null) ? 0 : val.hashCode());
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            HasValueId<?> other = (HasValueId<?>) obj;
            if (val == null) {
                if (other.val != null)
                    return false;
            } else if (!val.equals(other.val))
                return false;
            return true;
        }
    }

}
导入静态org.junit.Assert.assertEquals;
导入java.util.Objects;
导入org.junit.Test;
导入com.fasterxml.jackson.annotation.jsonautodect;
导入com.fasterxml.jackson.annotation.JsonCreator;
导入com.fasterxml.jackson.annotation.JsonProperty;
导入com.fasterxml.jackson.annotation.JsonTypeInfo;
导入com.fasterxml.jackson.annotation.JsonTypeInfo.As;
导入com.fasterxml.jackson.databind.JavaType;
导入com.fasterxml.jackson.databind.ObjectMapper;
公共类序列化问题{
//HasValue上没有@JsonTypeInfo
@试验
public void json\u HasValue\u Inf\u javaType()引发异常{
HasValue对象=新的HasValue(新的InfCls(1));
ObjectMapper ObjectMapper=新的ObjectMapper();
JavaType JavaType=objectMapper.getDeserializationConfig().getTypeFactory().ConstructParameterType(HasValue.class,Inf.class);
String serialized=objectMapper.writerFor(javaType).writeValueAsString(object);
HasValue反序列化=objectMapper.readValue(序列化,javaType);
assertEquals(对象,反序列化);
}
//HasValueId上的@JsonTypeInfo
@试验
public void json\u HasValueId\u Inf\u javaType()引发异常{
HasValueId对象=新的HasValueId(新的InfCls(1));
ObjectMapper ObjectMapper=新的ObjectMapper();
JavaType JavaType=objectMapper.getDeserializationConfig().getTypeFactory().ConstructParameterType(HasValueId.class,Inf.class);
String serialized=objectMapper.writerFor(javaType).writeValueAsString(object);
HasValueId反序列化=objectMapper.readValue(序列化,javaType);
assertEquals(对象,反序列化);
}
//====测试@JsonTypeInfo的接口和impl=====
@JsonTypeInfo(使用=JsonTypeInfo.Id.MINIMAL_类,包括=As.PROPERTY,PROPERTY=“@CLASS”)
公共静态接口Inf{
}
@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY,IsGettServiceability=JsonAutoDetect.Visibility.NONE,GettServiceability=JsonAutoDetect.Visibility.NONE,setterVisibility=JsonAutoDetect.Visibility.NONE)
公共静态类InfCls实现Inf{
私人国际旅行社;
@JsonCreator
公共InfCls(@JsonProperty(“val”)int val){
this.val=val;
}
@凌驾
公共字符串toString(){
返回“InfCls[val=“+val+”]”;
}
@凌驾
公共int hashCode(){
返回31*1+val;
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(getClass()!=obj.getClass())
返回false;
InfCls其他=(InfCls)obj;
如果(val!=其他.val)
返回false;
返回true;
}
}
//====具有值的类=====
@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY,IsGettServiceability=JsonAutoDetect.Visibility.NONE,GettServiceability=JsonAutoDetect.Visibility.NONE,setterVisibility=JsonAutoDetect.Visibility.NONE)
公共静态类HasValue{
私人终审法院;
@JsonCreator
public HasValue(@JsonProperty(“val”)A val){
this.val=Objects.requirennoull(val);
}
公共A get(){
返回val;
}
@凌驾
公共字符串toString(){
返回“HasValue[val=“+val+”]”;
}
@凌驾
公共int hashCode(){
返回31*1+((val==null)?0:val.hashCode();
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(getClass()!=obj.getClass())
返回false;
HasValue other=(HasValue)obj;
if(val==null){
如果(other.val!=null)
返回false;
}如果(!val.equals(other.val))
返回false;
返回true;
}
}
@JsonTypeInfo(use=JsonTypeInfo.Id.MINIMAL_类,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“@CLASS”)
@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY,IsGettServiceability=JsonAutoDetect.Visibility.NONE,GettServiceability=JsonAutoDetect.Visibility.NONE,setterVisibility=JsonAutoDetect.Visibility.NONE)
公共静态类HasValueId{
私人终审法院;
@JsonCreator
public HasValueId(@JsonProperty(“val”)A val){
this.val=Objects.requirennoull(val);
}
公共A get(){
返回val;
}
@凌驾
公共字符串toString(){
返回“HasValue[val=“+val+”]”;
}
@凌驾
公共int hashCode(){
返回31*1+((val==null)?0:val.hashCode();
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(getClass()=
public static class HasValueId<A extends Inf> {
    private final A val;
public static class HasValueId<A> {
    @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = As.PROPERTY, property = "@class")
    private final A val;