杰克逊的mixin类不能解决问题:bug还是我做错了什么?

fge*_*fge 1 java mixins jackson deserialization

这是杰克逊2.3.3.我最近在Jackson 学习了mixin注释,我正试图将它应用到课堂上.但到目前为止没有成功.有问题的类是另一个类的静态类:

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
}
Run Code Online (Sandbox Code Playgroud)

而且没有其他的构造者.因此我写了我的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
    )
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

因为没有"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)
Run Code Online (Sandbox Code Playgroud)

我真的不明白; 我做了注释mixin类的构造函数,@JsonCreator到目前为止它一直对我来说是"正常"的反序列化(这是我第一次尝试mixin).

这是杰克逊的错误还是我做错了什么?


编辑main::

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Module:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

wha*_*ley 6

确保mixin类上的ctor签名与目标类上的ctor签名匹配.您的目标类ctor的totalNanoTime为long,但您的mixin ctor的totalNanoTime为int.

?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
????????????????????????????? 
?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
?????????????????????????????
Run Code Online (Sandbox Code Playgroud)

这样的惊喜.

  • 很有感觉!很清楚! (2认同)