由于 jackson ,Java 二进制序列化失败

标签 java json serialization jackson

我使用 jackson 2 将 json 转换为 java 对象。到目前为止,一切都很好。但我也使用 hazelcast 将对象分布在一个集群中。因此所有 bean 都必须是 java.io.Serializable。当我像这样从 json 中读取对象时:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(AbstractBean.class, MongoIdMixIn.class);

// this is to prevent from failing on missing type class property: @JsonProperty("@class")
Object tgtObject = targetClass.newInstance();
mapper.readerForUpdating(tgtObject).readValue(dbo.toString());

// put into hazelcast map
target.put(dbo.get(keyColumn), tgtObject); 

我将从 hazelcast 得到一个异常(exception):

java.io.NotSerializableException: com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer

我想知道 com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer 是从哪里来的,因为对象是一个普通的 java bean(但使用继承)。

我的抽象类是:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@javaClass")
public abstract class AbstractBean implements Serializable {
    @JsonIgnore public static final transient IMarkupParser MARKUP_PARSER = new WikiMarkupParser();

    @JsonProperty("id")
    private String id;

    @JsonProperty("@class")
    private String clazz;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getClazz() {
        return this.getClass().getSimpleName();
    }
}

我的 child 是:

public class Posting extends AbstractBean {
    private String postingSource;
    private String languageCode;

    public String getPostingSource() {
        return postingSource;
    }

    public void setPostingSource(String postingSource) {
        this.postingSource = postingSource;
    }

    public String getLanguageCode() {
        return languageCode;
    }

    public void setLanguageCode(String languageCode) {
        this.languageCode = languageCode;
    }
}

我不知道为什么 serailizer 甚至会尝试序列化 mixins,因为它们不是 bean 的一部分,但它们在这里(是的,我也试图让它们序列化,只是作为测试,运气不好):

public interface IdMixins extends Serializable {
}

public interface MongoIdMixIn extends IdMixins {
    @JsonProperty("_id")
    @JsonSerialize(using = MongoIdSerializer.class)
    public String getId();

    @JsonProperty("_id")
    @JsonDeserialize(using = MongoIdDeserializer.class)
    public void setId(String id);
}

public class MongoIdDeserializer extends JsonDeserializer<String> implements Serializable {
    private static final long serialVersionUID = -5404276857799190647L;

    @Override
    public String deserialize(JsonParser jp, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        String value = null;

        String tmp = jp.getText(); // {
        validate(jp, tmp,"{");
        int curly = 1;

        while (jp.nextToken() != null) {
            String v = jp.getText();

            if (v.equals("{")) curly++;

            if (v.equals("$oid")) {
                jp.nextToken();
                value = jp.getText();
            }

            if (v.equals("}")) curly--;
            if (curly<=0) return value;
        }

        return null;
    }

    private void validate(JsonParser jsonParser, String input, String expected) throws JsonProcessingException {
        if (!input.equals(expected)) {
            throw new JsonParseException("Unexpected token: " + input, jsonParser.getTokenLocation());
        }
    }
}

public class MongoIdSerializer extends JsonSerializer<String> implements Serializable {
    private static final long serialVersionUID = 3435689991839324194L;

    @Override
    public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeFieldName("$oid");
        jsonGenerator.writeString(s);
        jsonGenerator.writeEndObject();
    }
}

最佳答案

我傻了!序列化链中的某处是一个完全不必要的 ObjectMapper 对象。但是很难找到,因为真正的原因不是 Posting 对象,而是另一个对象。但是 Stacktrace 和 com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer Exception 完全没有领先! ...集群软件有时调试起来真的很痛苦:-)

关于由于 jackson ,Java 二进制序列化失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30330048/

相关文章:

java - ThreadPoolExecutor 的 corePoolSize=0 如何工作?

用于实现 Map 和 List 的 JSON 值的 Java 包装类

php - 在个人资料页面上显示 JSON

c++ - 使用 boost 序列化为二进制存档。输入流错误

java - Appium iOS 自动化使用 Java : get element using accessibility Id?

用于 cucumber 测试的Java序列化

java - 如何将对象二进制(反)序列化为/形成字符串?

python - 如何将两个相似的 View 组合成一个响应?

java - 如何从 Java/JNDI 修改 OpenLDAP 中的操作属性?

javascript - 使用 $.ajax POST 将查询字符串参数传递给 WebService