Tuesday 30 March 2021

Generate POJOs from json document

Most of the time, in web application development, we need to define model classes in sync with json payload. What if there is a way to generate model POJO classes using json document…sounds nice right. In this post, I am going to explain how can you generate Java POJOs using json document.

 

Follow below step-by-step procedure to generate model classes.

 

Step 1: Define an instance of Jackson2Annotator. Jackson2Annotator class generates Java types using the Jackson 2.x mapping annotations.

GenerationConfig generationConfig = new DefaultGenerationConfig() {
	@Override
	public boolean isGenerateBuilders() {
		return true;
	}

	public SourceType getSourceType() {
		return SourceType.JSON;
	}
};

Jackson2Annotator jackson2Annotator = new Jackson2Annotator(generationConfig);

  Step 2: Define SchemaMapper instance. SchemaMapper generates Java types from a JSON schema. Can accept a factory which will be used to create type generation rules for this mapper.

 

SchemaStore schemaStore = new SchemaStore();
RuleFactory ruleFactory = new RuleFactory(generationConfig, jackson2Annotator, schemaStore);
SchemaMapper mapper = new SchemaMapper(ruleFactory, new SchemaGenerator());

Step 3: Reads schema and adds generated types to the given code model.

JCodeModel jCodeModel = new JCodeModel();

File inputJson = new File(INPUT_JSON_FILE);
URL inputJsonURL = inputJson.toURI().toURL();

mapper.generate(jCodeModel, "Employee", PACKAGE_NAME, inputJsonURL);


If the input file is located in classpath, you can get the file url using below statement.

URL inputJsonURL = PojoFromJsonDocument.class.getClassLoader().getResource(INPUT_JSON_FILE);

 

Step 4: Write the generated types to the output directory.

File outputPojoDirectory = new File(OUTPUT_DIR);
outputPojoDirectory.mkdirs();
jCodeModel.build(outputPojoDirectory);

 

Find the below working application.

 

employee.json

{
    "id": 1,
    "firstName": "Ram",
    "lastName": "Gurram",
    "address": {
        "street": "Chowdeswari",
        "city": "Bangalore",
        "country": "India"
    }
}

 

PojoFromJsonDocument.java

import java.io.File;
import java.io.IOException;
import java.net.URL;

import org.jsonschema2pojo.DefaultGenerationConfig;
import org.jsonschema2pojo.GenerationConfig;
import org.jsonschema2pojo.Jackson2Annotator;
import org.jsonschema2pojo.SchemaGenerator;
import org.jsonschema2pojo.SchemaMapper;
import org.jsonschema2pojo.SchemaStore;
import org.jsonschema2pojo.SourceType;
import org.jsonschema2pojo.rules.RuleFactory;

import com.sun.codemodel.JCodeModel;

public class PojoFromJsonDocument {
    private static final String INPUT_JSON_FILE = "employee.json";
    private static final String PACKAGE_NAME = "com.sample.app.model";
    private static final String OUTPUT_DIR = "/Users/Shared/json/modelClasses";

    public static void main(String[] args) throws IOException {

        GenerationConfig generationConfig = new DefaultGenerationConfig() {
            @Override
            public boolean isGenerateBuilders() {
                return true;
            }

            public SourceType getSourceType() {
                return SourceType.JSON;
            }
        };

        Jackson2Annotator jackson2Annotator = new Jackson2Annotator(generationConfig);

        SchemaStore schemaStore = new SchemaStore();
        RuleFactory ruleFactory = new RuleFactory(generationConfig, jackson2Annotator, schemaStore);
        SchemaMapper mapper = new SchemaMapper(ruleFactory, new SchemaGenerator());

        JCodeModel jCodeModel = new JCodeModel();

        URL inputJsonURL = PojoFromJsonDocument.class.getClassLoader().getResource(INPUT_JSON_FILE);

        mapper.generate(jCodeModel, "Employee", PACKAGE_NAME, inputJsonURL);

        File outputPojoDirectory = new File(OUTPUT_DIR);
        outputPojoDirectory.mkdirs();
        jCodeModel.build(outputPojoDirectory);
    }

}

 

Run the application, you will see following messages in console.

 

com/sample/app/model/Address.java

com/sample/app/model/Employee.java

 

You can observe Employee and Address classes are generated.

 

$tree /Users/Shared/json/modelClasses/
/Users/Shared/json/modelClasses/
└── com
    └── sample
        └── app
            └── model
                ├── Address.java
                └── Employee.java

4 directories, 2 files

 

Generated source code

Address.java

package com.sample.app.model;

import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "street",
    "city",
    "country"
})
@Generated("jsonschema2pojo")
public class Address {

    @JsonProperty("street")
    private String street;
    @JsonProperty("city")
    private String city;
    @JsonProperty("country")
    private String country;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonProperty("street")
    public String getStreet() {
        return street;
    }

    @JsonProperty("street")
    public void setStreet(String street) {
        this.street = street;
    }

    public Address withStreet(String street) {
        this.street = street;
        return this;
    }

    @JsonProperty("city")
    public String getCity() {
        return city;
    }

    @JsonProperty("city")
    public void setCity(String city) {
        this.city = city;
    }

    public Address withCity(String city) {
        this.city = city;
        return this;
    }

    @JsonProperty("country")
    public String getCountry() {
        return country;
    }

    @JsonProperty("country")
    public void setCountry(String country) {
        this.country = country;
    }

    public Address withCountry(String country) {
        this.country = country;
        return this;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

    public Address withAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
        return this;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(Address.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('[');
        sb.append("street");
        sb.append('=');
        sb.append(((this.street == null)?"<null>":this.street));
        sb.append(',');
        sb.append("city");
        sb.append('=');
        sb.append(((this.city == null)?"<null>":this.city));
        sb.append(',');
        sb.append("country");
        sb.append('=');
        sb.append(((this.country == null)?"<null>":this.country));
        sb.append(',');
        sb.append("additionalProperties");
        sb.append('=');
        sb.append(((this.additionalProperties == null)?"<null>":this.additionalProperties));
        sb.append(',');
        if (sb.charAt((sb.length()- 1)) == ',') {
            sb.setCharAt((sb.length()- 1), ']');
        } else {
            sb.append(']');
        }
        return sb.toString();
    }

    @Override
    public int hashCode() {
        int result = 1;
        result = ((result* 31)+((this.country == null)? 0 :this.country.hashCode()));
        result = ((result* 31)+((this.additionalProperties == null)? 0 :this.additionalProperties.hashCode()));
        result = ((result* 31)+((this.city == null)? 0 :this.city.hashCode()));
        result = ((result* 31)+((this.street == null)? 0 :this.street.hashCode()));
        return result;
    }

    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }
        if ((other instanceof Address) == false) {
            return false;
        }
        Address rhs = ((Address) other);
        return (((((this.country == rhs.country)||((this.country!= null)&&this.country.equals(rhs.country)))&&((this.additionalProperties == rhs.additionalProperties)||((this.additionalProperties!= null)&&this.additionalProperties.equals(rhs.additionalProperties))))&&((this.city == rhs.city)||((this.city!= null)&&this.city.equals(rhs.city))))&&((this.street == rhs.street)||((this.street!= null)&&this.street.equals(rhs.street))));
    }

}

 

Employee.java

package com.sample.app.model;

import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "id",
    "firstName",
    "lastName",
    "address"
})
@Generated("jsonschema2pojo")
public class Employee {

    @JsonProperty("id")
    private Integer id;
    @JsonProperty("firstName")
    private String firstName;
    @JsonProperty("lastName")
    private String lastName;
    @JsonProperty("address")
    private Address address;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonProperty("id")
    public Integer getId() {
        return id;
    }

    @JsonProperty("id")
    public void setId(Integer id) {
        this.id = id;
    }

    public Employee withId(Integer id) {
        this.id = id;
        return this;
    }

    @JsonProperty("firstName")
    public String getFirstName() {
        return firstName;
    }

    @JsonProperty("firstName")
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public Employee withFirstName(String firstName) {
        this.firstName = firstName;
        return this;
    }

    @JsonProperty("lastName")
    public String getLastName() {
        return lastName;
    }

    @JsonProperty("lastName")
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Employee withLastName(String lastName) {
        this.lastName = lastName;
        return this;
    }

    @JsonProperty("address")
    public Address getAddress() {
        return address;
    }

    @JsonProperty("address")
    public void setAddress(Address address) {
        this.address = address;
    }

    public Employee withAddress(Address address) {
        this.address = address;
        return this;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

    public Employee withAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
        return this;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(Employee.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('[');
        sb.append("id");
        sb.append('=');
        sb.append(((this.id == null)?"<null>":this.id));
        sb.append(',');
        sb.append("firstName");
        sb.append('=');
        sb.append(((this.firstName == null)?"<null>":this.firstName));
        sb.append(',');
        sb.append("lastName");
        sb.append('=');
        sb.append(((this.lastName == null)?"<null>":this.lastName));
        sb.append(',');
        sb.append("address");
        sb.append('=');
        sb.append(((this.address == null)?"<null>":this.address));
        sb.append(',');
        sb.append("additionalProperties");
        sb.append('=');
        sb.append(((this.additionalProperties == null)?"<null>":this.additionalProperties));
        sb.append(',');
        if (sb.charAt((sb.length()- 1)) == ',') {
            sb.setCharAt((sb.length()- 1), ']');
        } else {
            sb.append(']');
        }
        return sb.toString();
    }

    @Override
    public int hashCode() {
        int result = 1;
        result = ((result* 31)+((this.firstName == null)? 0 :this.firstName.hashCode()));
        result = ((result* 31)+((this.lastName == null)? 0 :this.lastName.hashCode()));
        result = ((result* 31)+((this.id == null)? 0 :this.id.hashCode()));
        result = ((result* 31)+((this.address == null)? 0 :this.address.hashCode()));
        result = ((result* 31)+((this.additionalProperties == null)? 0 :this.additionalProperties.hashCode()));
        return result;
    }

    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }
        if ((other instanceof Employee) == false) {
            return false;
        }
        Employee rhs = ((Employee) other);
        return ((((((this.firstName == rhs.firstName)||((this.firstName!= null)&&this.firstName.equals(rhs.firstName)))&&((this.lastName == rhs.lastName)||((this.lastName!= null)&&this.lastName.equals(rhs.lastName))))&&((this.id == rhs.id)||((this.id!= null)&&this.id.equals(rhs.id))))&&((this.address == rhs.address)||((this.address!= null)&&this.address.equals(rhs.address))))&&((this.additionalProperties == rhs.additionalProperties)||((this.additionalProperties!= null)&&this.additionalProperties.equals(rhs.additionalProperties))));
    }

}

 

 

 

 

 

 

 



 

 

Previous                                                    Next                                                    Home

No comments:

Post a Comment