从数组元素反序列化时,jackson2 中的 @ConstructorProperties 不起作用

发布于 2025-01-19 11:44:20 字数 3647 浏览 0 评论 0原文

我想使用@constructorproperties代替@jsoncreator,但在某些情况下看起来它不起作用。

jackson2中的@constructorproperties在从数组元素中进行挑选时不起作用。 Method1()和Method2()是否有任何方法可以与@constructorProperties一起使用?

我正在使用杰克逊2.13。 Java 11.

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.beans.ConstructorProperties;
import java.util.HashSet;
import java.util.Set;

class Scratch {
    public static void main(String[] args) throws JsonProcessingException {
        // THIS WORKS WHEN I USE @ConstructorProperties("value") ON CompId()
        method1();

        // THIS ONLY WORKS WHEN I USE @JsonCreator ON CompId()
        method2();
    }

    private static void method2() throws JsonProcessingException {
        Set<Long> compIds = new HashSet<>(1);
        compIds.add(123L);

        Dto1 dto1 = new Dto1(compIds);

        ObjectMapper objectMapper = new ObjectMapper();

        String str = objectMapper.writeValueAsString(dto1);

        Dto2 dto = objectMapper.readValue(str, Dto2.class);
        System.out.println(dto);
    }

    private static void method1() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        CompId compId1 = new CompId(123L);

        String str = objectMapper.writeValueAsString(compId1);

        CompId compId = objectMapper.readValue(str, CompId.class);
        System.out.println(compId);
    }


    public static class Dto1 {
        private final Set<Long> compIds;

        @ConstructorProperties("compIds")
        public Dto1(Set<Long> compIds) {
            this.compIds = compIds;
        }

        public Set<Long> getCompIds() {
            return compIds;
        }

        @Override
        public String toString() {
            return "Dto1{" +
                    "compIds=" + compIds +
                    '}';
        }
    }

    public static class Dto2 {
        private final Set<CompId> compIds;

        @ConstructorProperties("compIds")
        public Dto2(Set<CompId> compIds) {
            this.compIds = compIds;
        }

        public Set<CompId> getCompIds() {
            return compIds;
        }

        @Override
        public String toString() {
            return "Dto2{" +
                    "compIds=" + compIds +
                    '}';
        }
    }

    static class CompId {
        private long value;

        //@JsonCreator
        @ConstructorProperties("value")
        public CompId(long value) {
            this.value = value;
        }

        public long getValue() {
            return value;
        }



        @Override
        public String toString() {
            return "CompId{" +
                    "value=" + value +
                    '}';
        }
    }

}

This is the stacktrace I get:

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `Scratch$CompId` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (123)
 at [Source: (String)"{"compIds":[123]}"; line: 1, column: 13] (through reference chain: Scratch$Dto2["compIds"]->java.util.HashSet[0])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1728)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1353)

I want to use @ConstructorProperties instead of @JsonCreator but it looks like it doesn't work in some scenarios.

@ConstructorProperties in jackson2 does not work when deserializing from array elements.
Is there any way for both method1() and method2() to work with @ConstructorProperties?

I'm using jackson 2.13.
Java 11.

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.beans.ConstructorProperties;
import java.util.HashSet;
import java.util.Set;

class Scratch {
    public static void main(String[] args) throws JsonProcessingException {
        // THIS WORKS WHEN I USE @ConstructorProperties("value") ON CompId()
        method1();

        // THIS ONLY WORKS WHEN I USE @JsonCreator ON CompId()
        method2();
    }

    private static void method2() throws JsonProcessingException {
        Set<Long> compIds = new HashSet<>(1);
        compIds.add(123L);

        Dto1 dto1 = new Dto1(compIds);

        ObjectMapper objectMapper = new ObjectMapper();

        String str = objectMapper.writeValueAsString(dto1);

        Dto2 dto = objectMapper.readValue(str, Dto2.class);
        System.out.println(dto);
    }

    private static void method1() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        CompId compId1 = new CompId(123L);

        String str = objectMapper.writeValueAsString(compId1);

        CompId compId = objectMapper.readValue(str, CompId.class);
        System.out.println(compId);
    }


    public static class Dto1 {
        private final Set<Long> compIds;

        @ConstructorProperties("compIds")
        public Dto1(Set<Long> compIds) {
            this.compIds = compIds;
        }

        public Set<Long> getCompIds() {
            return compIds;
        }

        @Override
        public String toString() {
            return "Dto1{" +
                    "compIds=" + compIds +
                    '}';
        }
    }

    public static class Dto2 {
        private final Set<CompId> compIds;

        @ConstructorProperties("compIds")
        public Dto2(Set<CompId> compIds) {
            this.compIds = compIds;
        }

        public Set<CompId> getCompIds() {
            return compIds;
        }

        @Override
        public String toString() {
            return "Dto2{" +
                    "compIds=" + compIds +
                    '}';
        }
    }

    static class CompId {
        private long value;

        //@JsonCreator
        @ConstructorProperties("value")
        public CompId(long value) {
            this.value = value;
        }

        public long getValue() {
            return value;
        }



        @Override
        public String toString() {
            return "CompId{" +
                    "value=" + value +
                    '}';
        }
    }

}

This is the stacktrace I get:

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `Scratch$CompId` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (123)
 at [Source: (String)"{"compIds":[123]}"; line: 1, column: 13] (through reference chain: Scratch$Dto2["compIds"]->java.util.HashSet[0])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1728)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1353)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文