On Tuesday, February 12, 2019 at 11:43:38 PM UTC-5, John Passaro wrote:
>
> On Tue, Feb 12, 2019, 23:02 Tatu Saloranta wrote:
>
>> On Tue, Feb 12, 2019 at 1:18 PM John Passaro wrote:
>> >
>> > Hello folks! I am trying to deserialize a yaml file with anchors and
>> references. There are some existing StackOverflow questions along these
>> lines but the answers aren't quite getting me to the finish line.
>> >
>> > [...]
>> >
>> >
>> > The idea is that I have lists that may be referenced more than once in
>> the "contents" tree, and I'd like to be able to reference them concisely.
>> >
>> > [...]
>> >
>> > With Jackson (2.9), I get an error:
>> >
>> > Exception in thread "main"
>> com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot
>> deserialize instance of java.util.ArrayList out of VALUE_STRING token
>> > at [Source: (File); line: 14, column: 13] (through reference chain:
>> YamlScratch["contents"]->java.util.LinkedHashMap["letters"]->YamlScratch$Config["labels"])
>> >
>> > [...]
>> >
>> > Is this behavior supported at all? If so, what do I need to do to make
>> it work?
>> >
>> > Many thanks in advance for your help. I'd be happy to post the results
>> on the relevant SO threads to make sure this information get shared
>> reasonably widely.
>>
>> Ok. I think I can point to the problem itself at least.
>>
>> For Jackson to handle anchors and references, property value types (or
>> property declarations) need `@JsonIdentityInfo`; otherwise Jackson
>> does not know to look for, or keep track of, anchors (ids for values
>> to reference) or references.
>>
>> But one limitation is that only POJO types support Object Id handling,
>> and here references would be to Lists of Strings (or maybe Lists of
>> Lists). In theory it would be possible to handle Object Ids for
>> Collection, Map and array types, but they are not supported at this
>> point.
>>
>> It might, however, be possible for you to create POJO type that gets
>> serialized as yaml/json Array, just like List (and deserialized from
>> as well). This could work by using combination of `@JsonValue` (to get
>> `List` to serialize) and `@JsonCreator` annotated constructor that
>> takes actual `List` value you want; or, using Converters. Either way
>> once you get that working, and type itself annotated with
>> `@JsonIdentityInfo` it should work.
>>
>> I know this is sub-optimal and leaves out some valid YAML cases. But
>> it just might work for your usage.
>>
>> I hope this helps,
>>
>> -+ Tatu +-
>>
>
> I will certainly try this out, it does seem like it would address my need.
> Thank you for the close attention to the example and for your suggestion.
> If it works I'll post my findings (i.e. working example) here and maybe add
> to those SO questions.
>
> It seems to me there might be a friendlier experience if there was a
> YamlParser.Feature to treat the entire document as having the
> JsonIdentityInfo annotation, including Lists and Maps and their contents -
> that is, resolving anchor references everywhere without the need for
> indicating where the user expects them to be. I don't know enough to assert
> that this is closer to the intention of the anchor/reference feature or of
> an average document that uses it, but it is closer to how PyYAML treats
> them, which I've found very useful. I hope you'll consider supporting such
> usage.
>
> Regardless, thank you for your help and for your work on this powerful
> library.
>
> Sadly this did not work. Here is my best shot based on how I understood
the suggestion:
@JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
class ScratchModel {
@JsonProperty("contents")
@JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
Map<String, Config> contents;
@JsonProperty("misc")
@JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
Misc misc;
@JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
static class Config {
@JsonProperty("header")
String header;
@JsonProperty("labels")
@JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
List<String> labels;
}
@JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
private static class Misc {
@JsonCreator
Misc(List<MiscInner> inners) { }
}
@JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
private static class MiscInner {
@JsonCreator
MiscInner(List<String> strings) { }
}
}
So I broke down the "misc" field, previously List<List<String>>, into a
type Misc that creates itself from List<MiscInner>, and MiscInner which
creates itself from List<String>. I added the @JsonIdentityInfo annotation
to every class and property that could plausibly need it.
Still getting the same error!
Here is the failing YAML again, for reference:
misc:
- &letters
- Aie
- Bee
- See
- &numbers
- One
- Two
- Three
contents:
letters:
header: "This is a list of phonetic letters"
labels: *letters
numbers:
header: "This is a list of number spellings"
labels: *numbers
moreletters:
header: "this is another copy of the letters"
labels: *letters
--
You received this message because you are subscribed to the Google Groups
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.