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