Friday, January 13, 2012

Utility to generate POJO classes for Json req/resp

JSON is widely used as request/response type in web services. We normally create POJO classes manually to hold the request/response json data.
Attached is the utility class to generate VO classes(POJO classes) from json sample request/response. If it works as expected, then it may save us from manually creating multiple classes for a single request/response.
This code assumes that the attributes of those classes can be of below 7 types:
1) String
2) Long
3) Double
4) Boolean
5) Object of custom classes
6) List of strings
7) List of numbers
8) List of custom objects

Steps to use this utility:
1) unzip the zip file(link of this zip file is given at the end of this blog) to any location in your machine.
2) create a folder with name "output" inside the root folder(same directory where class file is present). This is one time activity. Delete all the existing files from "output" folder if present.
3) copy the sample json request/response and paste into json.txt file
4) open json.bat file in edit mode and add the parent class file name. For e.g.: if you want to generate the class with file name WebServiceInput, then the content of this bat file should be
java JsonGenerator WebServiceInput
5)Run the json.bat file, it will generate all the VOs inside output folder.
6) Copy all the VOs inside correct package folder and add package statement to all class files.
7) this utility writes the contents of POJO class in 1 single line(without any formatting), it can be later be formatted using eclipse or any other tool.

I also attached the source code in the zip file, so that you can change the code to customize for your needs.

Note -
1)This utility may give error while running with wrongly formatted json. Please make sure that the json format is correct. It will also give error if any of the key-value pair have value as null, since with "null" as value, we can't figure out the datatype of key.
2) I am converting json property names to camel case to follow java naming convention. For e.g.: for element "name", the POJO class will have attribute with name "name"(same as json element), but for json element "Name", the generated class will have attribute with name "name"(changed to camel case). But most of the mapper requires the json element name and POJO class attribute name to be exactly same. In those cases, either you may need to remove the camel case conversion logic from the utility source code, or add some kind of mapping in the generated POJO class. Jackson mapper provides annotations to do this kind of mapping.
@JsonProperty("Name")
private String name





Please try to use this and let me know the issues you have faced while using this.

Link of zip file: https://docs.google.com/open?id=0B8O-miA80x0gOWNTckRsZG5tWnM


9 comments:

  1. Good info on how to parse JSON response but Your code fails under this scenario, Consider a JSON response like,

    {
    "employee" : [
    {
    "ID":20,
    "PHONE":["1234", "2346"],
    "GROUP":["abc", "acd"]
    }
    ]
    }
    The code will fail to form setters and getters for the variable GROUP since the attribute PHONE is an array and this ends with "]". The code exits once it see's this "]" thinking that employee parsing is done.

    ReplyDelete
    Replies
    1. Thanks a lot Sunand for your valuable feedback. There was an unwanted "break" statement in the code. I fixed this issue and uploaded the new jar. Please let me know if you face any other issue.

      Delete
    2. Thanks for sharing this code.....really good utility

      Delete
  2. Hi, even i noticed that break statement and i had removed it in my code, But the bigger problem occurs when i try to retrieve a JSON response stream and give this as input to the JsonGenerator class. Consider the following JSON response,

    {
    "employee" : [
    {
    "ID":20,
    "PHONE":["1234", "2346"],
    "GROUP":["abc", "acd"]
    },
    {
    "ID":21,
    "PHONE":["1234", "2346"],
    "GROUP":["abc", "acd"]
    }
    ]
    }

    What happens here is the code adds "GROUP" details to the main class which in this case is MyClass by default. Ideally MyClass should have only List getters & setters. It has something to do with how square brace is handled in the code. I had put a flag to check a square braces and break out of the situation to avoid the above problem but this is just a workaround. If you can fix this it would be great.

    ReplyDelete
    Replies
    1. Hi, this issue is also fixed. Uploaded the new code.
      Please let me know if you face any other issue.

      Delete
    2. Hi, Thanks for the fix. I had written something like this,
      if("]".equals(jsonList.peek()) break; but what you have given now is a better one. This saves a lot of time in doing the analysis, THANKS! I will get back to you if i find any other issue or if i do any enhancements to the code. One tip would be to comment out the change to Camel case function. If i have to map a JSON response to pojo the variable name should be same.

      Delete
    3. Thanks for helping in improving the code. Regarding your suggestion about commenting changeToCamelCase method, I kept it to follow java naming convention(keeping variable names, functions names in camel case), but we can change it depending on our need and requirement. Also most of the mappers requires variable name to be same as the json element name, so it is good idea not to change the variable name to camel case. So, probably we can comment it.

      Delete
  3. Nice utility, is there a limited to the numbers of set and get it will create. I run a json file with 117 and it only created the __metadata file then I tried one with 24 and it worked fine until it got to a date field then it messed up. But I got all three class files.
    If you would like I can send you the json files.

    ReplyDelete
    Replies
    1. Hey Kim,
      I never tested this with more than 20 fields in the same class. Also I never tried with date field. It would be great if you could share the JSON files, then I will try to fix these issues.

      Tx

      Delete