32

I am trying to create the inner class type for an object being passed in as JSON but while I have read tons on here as well as Jackson's site I don't seem to be able to get the right combination so if anyone else has any pointers they would be much appreciated. I've posted some snippets below and removed all getters and setters, I didn't figure they needed posting. I'm using Jackson 2.2.

The classes I'm attempting to deserialize:

public class Settings {
  private int offset;
  private int limit;
  private String type;
  private Map<String, Criteria> criteria;

  public class Criteria {
    private String restriction;
    private Object value;
  }
}

The code I'm using to deserialize:

ObjectMapper om = new ObjectMapper();
TypeFactory tf = om.getTypeFactory();
JavaType map = tf.constructMapLikeType( Map.class, String.class, Criteria.class );
JavaType type = typeFactory.constructType( Settings.class, map );
Settings settings = om.readValue( entity, type );

My JSON testing data:

{ "type": "org.json.Car", "criteria": { "restriction": "eq", "value": "bmw" } }
ars265
  • 1,949
  • 3
  • 21
  • 37
  • 2
    The inner class must be static. See http://www.cowtowncoder.com/blog/archives/2010/08/entry_411.html – Paul Feb 04 '15 at 15:36
  • When following those instructions I get the error: "The member type [class name] cannot be declared static; static types can only be declared in static or top level types" – coltonfranco Feb 06 '17 at 17:31
  • Refer to this blog post for more info about nesting classes and jackson. Serialization works fine, but deserialization won't unless the class is static nested type - http://www.cowtowncoder.com/blog/archives/2010/08/entry_411.html – MasterJoe Nov 20 '17 at 21:17

2 Answers2

85

The correct answer is that you are missing the static keyword on the inner class.

Just make sure that the "static" keyword is there.

Read http://www.cowtowncoder.com/blog/archives/2010/08/entry_411.html

it takes you 3 minutes but make you happy for the rest of the day.

redochka
  • 12,345
  • 14
  • 66
  • 79
  • 4
    This should be the accepted answer. – Lucas Kuhlemann Sep 19 '16 at 20:20
  • 1
    redochka - How do we decide whether to use static nested class (your anwser) or simply composition (juned ahsan answer.) ? – MasterJoe Nov 20 '17 at 21:19
  • 5
    @testerjoe2 it is a matter of personal choice. I use a nested static class when i know it won't be used elsewhere because it is tightly related to the hosting class. If i am going to use this class elsewhere i put it in a separate class for sure. – redochka Nov 21 '17 at 06:58
  • Besides, options should be also considered from a readability perspective. Past some few hundred LOC, it's just better to have a separate file for your inner classes. – buer Jun 16 '18 at 16:23
  • @testerjoe2 if you have a bunch of private methods that all take in the same set of parameters in the signature, then you can refactor that into a private non-static inner class that injects those parameters into the class so that the methods only take in unique parameters. This is especially useful for iterative processors that share common data across the items being iterated. Static inner classes are better for public classes that simply make more semantic sense, like FooProcessor.Parameters and FooProcessor.Result – Novaterata Sep 25 '18 at 16:05
  • Have read this article. So, AFAIK the main problem is in the hidden constructor of inner non static classes. But why it still not working if we manually add the default constructor(no arguments) for the inner class? – chill appreciator Oct 09 '19 at 22:26
18

If you can, then make your life simple and move the inner class to a normal class with a reference in the Settings class. And then do the marshalling using jackson, here is how you can have your classes:

public class Settings {
  private int offset;
  private int limit;
  private String type;
  private Map<String, Criteria> criteria;
  private Criteria criteria;
}


 class Criteria {
    private String restriction;
    private Object value;
  }
Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136