java - Jackson 的 mixin 类不能解决问题 : bug or am I doing something wrong?

标签 java jackson deserialization mixins

这是 jackson 2.3.3。我最近了解到 mixin annotations在 jackson ,我正在尝试将其应用到类里面。然而到目前为止还没有成功。有问题的类是一个静态类到另一个类:

public static class Report
{
    // Some non relevant public static final fields, then:

    public final int totalRuns;
    public final int totalInvocations;
    public final int totalMatches;
    public final int totalMismatches;
    public final double matchShare;
    public final int reinvocations;
    public final int rematches;
    public final int remismatches;
    public final double reinvocationShare;
    public final long totalNanoTime;
    public final List<RuleReport> ruleReports;

    public Report(final int totalRuns, final int totalMatches,
        final int totalMismatches, final int rematches,
        final int remismatches, final long totalNanoTime,
        final List<RuleReport> ruleReports)
    {
        this.totalRuns = totalRuns;
        this.totalInvocations = totalMatches + totalMismatches;
        this.totalMatches = totalMatches;
        this.totalMismatches = totalMismatches;
        this.matchShare = (double) totalMatches / (double) totalInvocations;
        this.reinvocations = rematches + remismatches;
        this.rematches = rematches;
        this.remismatches = remismatches;
        this.reinvocationShare = (double) reinvocations
            / (double) totalInvocations;
        this.totalNanoTime = totalNanoTime;
        this.ruleReports = ruleReports;
    }
    // Other, non relevant methods
}

并且没有其他构造函数。因此我这样写了我的 mixin 类:

public abstract class ProfilingReportMixin
{
    @JsonProperty("runs")
    private int totalRuns;
    @JsonIgnore
    private int totalInvocations;
    @JsonProperty("matches")
    private int totalMatches;
    @JsonProperty("mismatches")
    private int totalMismatches;
    @JsonIgnore
    private double matchShare;
    @JsonIgnore
    private int reinvocations;
    @JsonProperty("rematches")
    private int rematches;
    @JsonProperty("remismatches")
    private int remismatches;
    @JsonIgnore
    private double reinvocationShare;
    @JsonIgnore
    private long totalNanoTime;
    @JsonProperty("ruleReports")
    private List<RuleReport> ruleReports;

    @JsonCreator
    protected ProfilingReportMixin(
        @JsonProperty("runs") final int totalRuns,
        @JsonProperty("matches") final int totalMatches,
        @JsonProperty("mismatches") final int totalMismatches,
        @JsonProperty("rematches") final int rematches,
        @JsonProperty("remismatches") final int remismatches,
        @JsonProperty("totalNanoTime") final int totalNanoTime,
        @JsonProperty("ruleReports") final List<RuleReport> ruleReports
    )
    {
    }
}

由于没有“bean 构造函数”,显然我决定采用 @JsonCreator 方式。

我创建了 Module,注册了它,没问题...除了在尝试反序列化示例 JSON 时它失败了:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class org.parboiled.parserunners.ProfilingParseRunner$Report]: can not instantiate from JSON object (need to add/enable type information?)
 at [Source: java.io.BufferedInputStream@b41b571; line: 2, column: 5]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1078)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:268)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:124)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2993)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2144)
    at com.github.parboiled1.grappa.assertions.mixins.ProfilingReportMixin.main(ProfilingReportMixin.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

我不是很明白;我确实用 @JsonCreator 注释了 mixin 类的构造函数,到目前为止它一直对我有用,用于“正常”反序列化(这是我第一次尝试 mixin)。

这是 Jackson 的错误还是我做错了什么?


编辑:主要:

public static void main(final String... args)
    throws IOException
{
    final ObjectMapper mapper = new ObjectMapper()
        .configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
    mapper.registerModule(GrappaModule.INSTANCE);

    final Closer closer = Closer.create();
    final InputStream in;

    try {
        in = closer.register(ProfilingReportMixin.class.
            getResourceAsStream("/profilingReports/test.json"));
        if (in == null)
            throw new IOException("resource not found");
        final ProfilingParseRunner.Report report
            = mapper.readValue(in, ProfilingParseRunner.Report.class);
        mapper.writerWithDefaultPrettyPrinter()
            .writeValue(System.out, report);
    } finally {
        closer.close();
    }
}

模块:

public final class GrappaModule
    extends SimpleModule
{
    private static final Version VERSION = new Version(1, 0, 0,
        "beta.5-SNAPSHOT", "com.github.parboiled1", "grappa");

    public static final Module INSTANCE = new GrappaModule();

    private GrappaModule()
    {
        super("grappa", VERSION);
    }

    @Override
    public void setupModule(final SetupContext context)
    {
        context.setMixInAnnotations(ProfilingParseRunner.RuleReport.class,
            RuleReportMixin.class);
        context.setMixInAnnotations(ProfilingParseRunner.Report.class,
            ProfilingReportMixin.class);
    }
}

最佳答案

确保您的 mixin 类上的构造函数签名与您的目标类上的构造函数签名相匹配。您的目标类构造函数将 totalNanoTime 作为 long,但您的混合构造函数将 totalNanoTime 作为 int。

░░░░░░░░░▄░░░░░░░░░░░░░░▄░░░░
░░░░░░░░▌▒█░░░░░░░░░░░▄▀▒▌░░░
░░░░░░░░▌▒▒█░░░░░░░░▄▀▒▒▒▐░░░
░░░░░░░▐▄▀▒▒▀▀▀▀▄▄▄▀▒▒▒▒▒▐░░░
░░░░░▄▄▀▒░▒▒▒▒▒▒▒▒▒█▒▒▄█▒▐░░░
░░░▄▀▒▒▒░░░▒▒▒░░░▒▒▒▀██▀▒▌░░░ 
░░▐▒▒▒▄▄▒▒▒▒░░░▒▒▒▒▒▒▒▀▄▒▒▌░░
░░▌░░▌█▀▒▒▒▒▒▄▀█▄▒▒▒▒▒▒▒█▒▐░░
░▐░░░▒▒▒▒▒▒▒▒▌██▀▒▒░░░▒▒▒▀▄▌░
░▌░▒▄██▄▒▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒▌░
▀▒▀▐▄█▄█▌▄░▀▒▒░░░░░░░░░░▒▒▒▐░
▐▒▒▐▀▐▀▒░▄▄▒▄▒▒▒▒▒▒░▒░▒░▒▒▒▒▌
▐▒▒▒▀▀▄▄▒▒▒▄▒▒▒▒▒▒▒▒░▒░▒░▒▒▐░
░▌▒▒▒▒▒▒▀▀▀▒▒▒▒▒▒░▒░▒░▒░▒▒▒▌░
░▐▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▒▄▒▒▐░░
░░▀▄▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▄▒▒▒▒▌░░
░░░░▀▄▒▒▒▒▒▒▒▒▒▒▄▄▄▀▒▒▒▒▄▀░░░
░░░░░░▀▄▄▄▄▄▄▀▀▀▒▒▒▒▒▄▄▀░░░░░
░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▀▀░░░░░░░░

太神奇了。

关于java - Jackson 的 mixin 类不能解决问题 : bug or am I doing something wrong?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23517120/

相关文章:

java - 使用 Jackson 序列化时,如何仅在 JSON 中而不是字符串中保留 Long 作为数字?

java - @JsonIgnore 有条件

java - Jackson ObjectMapper setSerializationInclusion() 不工作

python - JSON 到类实例?

java - 当我尝试创建图像文件时,try-catch 没有捕获 IOException

java - clojure 与 mysql 和 java

java - 如何使用QueryParser进行Lucene范围查询(IntPoint/LongPoint)

java - TreeSet 忽略值

c# - 无法使用 whis json 反序列化当前 JSON 对象

C# - 从 JSON 反序列化,结果始终是一个空对象