-4

I have been trying to create json from a java object / class that has a nested class. However only the top level class is output in Json. I want to return json from a web services application or alternatively covert json to a java object with nested classes

public class JsonData {
    static String firstName;
    static String lastName;
    static String streetName;
    static String cityName;
    static String stateName;

    static PersonalInfo personalInfo = new PersonalInfo(); 

 //  typical set and get followed by the nested class
     static class PersonalInfo {
     String height;
     String weight;
     String eyeColor;
     String favoriteColor;
     // getter's and setters for this class
     }
   }

    // in a separate method that handles the web service request set the values... 

   @RequestMapping(value = "/json", method = RequestMethod.GET)
public @ResponseBody String sendJsonSample() throws JsonGenerationException {
    ObjectMapper jsonMapper = new ObjectMapper();
    System.out.println("\nReceived Request for json data what happens now ! \n");
    JsonData jsonData = new JsonData();
    jsonData.setCityName("New York");
    jsonData.setFirstName("Fred");
    jsonData.setLastName("Smith");
    jsonData.setStateName("NY");
    jsonData.setStreetName("Broadway");
    JsonData.personalInfo.setEyeColor("Green");
    JsonData.personalInfo.setFavoriteColor("Yellow");
    JsonData.personalInfo.setHeight("SixFeet");
    JsonData.personalInfo.setWeight("180");

      // now convert to json with the following
      try {
        String json = jsonMapper.writeValueAsString(jsonData);
        return json;
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }       
      return "ERROR"
     }

    // if I use a browser to my controller http://localhost:8080/json the json returned to my web services call only includes the top or outer level class 
    {
      stateName: "NY",
      firstName: "Fred",
      lastName: "Smith",
      streetName: "Broadway",
      cityName: "New York"
    }

    // I would have expected or I want I should say 
    {
     "state": "NY",
     "firstName": "Fred",
     "lastName": "Smith",
     "streetName": "Broadway",
     "cityName": "New York",
     "PersonalInfo": {
       "EyeColor":"Green",
       "FavoriteColor": "Yellow",
       "height":"SixFeet",
       "Weight":"189"
     }
    }
TKPhillyBurb
  • 91
  • 3
  • 11

1 Answers1

0

Jackson serializes objects and instance properties. Your class defines all of its members as _class_members -- i.e., static. That means that no matter how many objects are instantiated from your class, there will be only one value for each static property. Every piece of code that sets the value of one of those properties will change it for every other piece of code reading it.

Perhaps you have made your properties static because your PersonalInfo nested class class is static. Remove the static modifier from your PersonalInfo class. Even better, make it a top-level class and remove the static modifier.

An aside: Because your code will be used in a web application, your class will be instantiated by many threads. Using non-final static members in data classes such as this is very, very hazardous. All of your clients will be sharing the same data.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
Tony Pierce
  • 788
  • 1
  • 6
  • 11
  • The class being nested and `static` is not an issue. Making it non-static will complicate and potentially break things further as Jackson won't necessarily have an enclosing instance to instantiate it with. – Sotirios Delimanolis May 17 '16 at 20:48
  • This is simply a sample app to get this to work the hazards are understood. I'm still not understanding why the output json is not as I would expect. Thanks – TKPhillyBurb May 17 '16 at 20:50
  • Not serializing static members would have been a design decision by the Jackson developers. I have to ask why would you ever want the properties such as these to be static? – Tony Pierce May 17 '16 at 20:55
  • The properties are definitely at the heart of the issue. The class declaration is not. – Sotirios Delimanolis May 17 '16 at 20:56
  • You're right Sotirios -- I was thinking of the inner class needing access to the enclosing class's properties, which would be inaccessible if the inner class wasn't static. I didn't look carefully enough at the code example :-o – Tony Pierce May 17 '16 at 20:58
  • I had researched this and found an answer (which does not seem to work for me) indicating this needing to be static. http://stackoverflow.com/questions/17289964/jackson-json-type-mapping-inner-class So I'm trying to get around why this won't work. – TKPhillyBurb May 17 '16 at 20:58