1

I am trying to deserialize a JSON String like (extracted this bit to show the issue)

{
    "$type": "com.example.StringProperty",
    "value": "hello world",
    "name": "text",
    "readOnly": false
}

into a hierarchy of classes that look like

public class Property
{
    public String name;
    public int    type;

    Property(String pName, int pType) { name = pName; type = pType; }
}

public class StringProperty extends Property 
{
    public String value;        
    StringProperty(String pName, String pValue) {
        super(pName, String);
        value = pValue;
    }       
}

using the following mixin annotations

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="$type")
abstract public class PropertyMixin
{
    @JsonProperty
    public String name;
    //@JsonIgnore
    //public boolean readOnly;
    @JsonProperty
    public int type;

    PropertyMixin(@JsonProperty("name") String pName, @JsonProperty("type") int pType)
    {
    }
}

abstract public class StringPropertyMixin
{
    @JsonProperty
    public String value;
    //@JsonIgnore
    //public boolean readOnly;

    @JsonCreator
    public StringPropertyMixin(@JsonProperty("name") String pName, @JsonProperty("value") String value)
    {
    }
}

With Jackson 1.9.2, the error I am getting is

Unrecognized field "readOnly" (Class com.example.StringProperty), not marked as ignorable

I tried using @JsonIgnore, but that did not help (check the locations of the code I commented out to see how I tried it). I am probably missing something, but I think another set of eyes need to look at it and help me.

This is how the deserialization environment looks like:

        objectMapper.setVisibilityChecker(objectMapper.getSerializationConfig().getDefaultVisibilityChecker()
                .withFieldVisibility(JsonAutoDetect.Visibility.NONE)
                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));

        MixinRegistrations module = new MixinRegistrations();
        objectMapper.registerModule(module);

and mixin module looks like

@Override
public void setupModule(SetupContext context)
{
    context.setMixInAnnotations(Property.class, PropertyMixin.class);
    context.setMixInAnnotations(StringProperty.class, StringPropertyMixin.class);
}

I appreciate all the help. Thanks in advance.

PS: I do not know if this makes a difference but the JSON is being generated by a library written in .Net Framework v4.

alokoko
  • 1,405
  • 4
  • 21
  • 35

3 Answers3

3

I believe Jackson is having problems because the method that you have delegated as a creator does not have a parameter for the readOnly field. So rather than silently ignore this missing parameter Jackson is throwing an error (good behaviour). Try using the JsonIgnoreProperties annotation. I've not had need to use if before, but for deserialisation you can explicitly denote fields that are not required by the creator.

Oh, this appears related as well.

Edit: Another question that the asker found that was useful.

Community
  • 1
  • 1
Dunes
  • 37,291
  • 7
  • 81
  • 97
  • Yes, you can add @JsonIgnoreProperties(ignoreUnknown = true) if that's the behavior you want – Alejandro Diaz Dec 07 '11 at 21:48
  • @Dunes: How does `@JsonIgnoreProperties` help if `@JsonIgnore` is not working in this situation? It looks like `@JsonIgnoreProperties` just an extension of `@JsonIgnore` to multiple values. – alokoko Dec 07 '11 at 21:53
  • I understood why `@JsonIgnore` did not work in my case but `@JsonIgnoreProperties` works fine after reading [this post](http://stackoverflow.com/questions/7438474/what-is-wrong-with-my-jsoncreator-and-mixin-annotation). Thanks for pointing out `@JsonIgnoreProperties` annotation. – alokoko Dec 08 '11 at 16:05
  • @alokoko Difference is that `@JsonIgnoreProperties` is added at class-level, and can be used to ignore JSON properties by name; whereas `@JsonIgnore` only ignores specific property, and you must have a field or setter/getter to attach it to. – StaxMan Dec 08 '11 at 16:05
  • 1
    @StaxMan: the part "and you must have a field or setter/getter to attach it to" is important. What I also had missed initially was that this statement should read as "and you must have a field or setter/getter to attach it to in the target class", since I already had that field in my mixin class, but it did not work. I got it after reading another reply from you in [another post](http://stackoverflow.com/questions/7438474/what-is-wrong-with-my-jsoncreator-and-mixin-annotation). – alokoko Dec 08 '11 at 16:11
  • @alokoko Glad you were able to find a solution. Will add the links to the answer. – Dunes Dec 08 '11 at 16:25
3

Note that your problem is NOT that class has a property Jackson does not recognize, but rather that JSON has a property. As such you may want to read this wiki page.

As mentioned, @JsonIgnoreProperties would work here, since adding that annotation to a class does not require a field or setter, unlike @JsonIgnore does. Plus it can be used to ignore any and all unknown properties.

StaxMan
  • 113,358
  • 34
  • 211
  • 239
  • Thanks for the link. 30 seconds before your answer, I posted a comment about how I understood how things worked. :-) – alokoko Dec 08 '11 at 16:08
0
@JsonIgnoreProperties({"propX", "propY"})

Would work just fine at class level!

Nisarg Panchal
  • 131
  • 1
  • 6