I am Computer Engineer by profession, passionate about technological advances in software technology, enthusiast learner. Also loves to read literature of historical & social importance.
Every software developer works with Integrated development environments (IDE) like eclipse, netbeans, MS Visual Studio etc. It gives them easy way to write code, that helps. Perhaps while building a project into distribution package, simple IDE may not be of help, since role of IDE is to support individual developer and not the project team.
Hence there comes need of build tool, which would automate several tasks of build process like shutdown servers, compile code, automate tests and generate reports etc. Maven can be viewed as build tool that can help us address these areas with industry standard and industry supported plugins.
However, Maven is more than a build tool. It can do automatic dependency resolution and distribution. It can help manage project source tree across different teams and repositories. It can generate ready to start framework with respect to type of architecture say simple java project that distributes JAR, simple web application that distributes WAR or complex enterprise application that distributes EAR.
Maven is open source tool backed by vast community. It is basically a plugin framework, with extensive set of ready made plugins which we can use or we can write custom one that solves specific problem of life. Hence it is extensible as well.
Several IDEs too support maven. For sake of simplicity and my family of JAVA, we will use eclipse to demonstrate the maven.
Jackson Streaming provides set of Streaming APIs to read from or Write to JSON as string. It is streaming oriented hence takes less memory footprint, it is analogous to Stax Streaming API for XML operations.
We will see simple example to write JSON string into .json file. Then read .json for input JSON string to be converted to Java Map object.
App.java
package custom.jackson.learning;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
public class App {
public static void main(String[] args) throws IOException {
//Write to JSON string to .json file
JsonFactory jsonFactory = new JsonFactory();
JsonGenerator jsonGenerator = jsonFactory.createGenerator(new File("Employee.json"), JsonEncoding.UTF8);
//start writing the JSON object
jsonGenerator.writeStartObject();
//"firstName":"Suresh"
jsonGenerator.writeStringField("firstName", "Suresh");
//"lastName":"Rana"
jsonGenerator.writeStringField("lastName", "Rana");
//"skills":["Java","PHP","SQL"]
jsonGenerator.writeFieldName("skills");
jsonGenerator.writeStartArray();
jsonGenerator.writeString("Java");
jsonGenerator.writeString("PHP");
jsonGenerator.writeString("SQL");
jsonGenerator.writeEndArray();
//"certified":true
jsonGenerator.writeBooleanField("certified", true);
//"age":21
jsonGenerator.writeNumberField("age", 21);
//end writing the JSON object
jsonGenerator.writeEndObject();
jsonGenerator.close();
System.out.println("JSON Writing to Employee.json completed.");
//read the JSON file as input and convert to Map object
System.out.println("Reading data from Employee.json file");
ObjectMapper mapper = new ObjectMapper();
Map employeeMap = mapper.readValue(new File("Employee.json"), Map.class);
System.out.println("Map created from Employee.json file ::"+employeeMap);
}
}
JSON String can also be parsed by Tree, analgous to DOM tree for XML parsing. Jackson provides the set of APIs that will take JSON string as input and it will parse it to form in-memory JSON tree. It provides set of APIs to navigate the tree.
We will see simple example to do so
Here App.java that takes input JSON string and prepares JSON tree for navigation.
package custom.jackson.learning;
import java.util.Iterator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class App {
public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
// TODO Auto-generated method stub
ObjectMapper mapper = new ObjectMapper();
// input JSON string
String jsonString = "{\"firstName\":\"Suresh\", \"lastName\":\"Rana\", "
+ " \"skill\":[\"Java\",\"PHP\",\"SQL\"] , "
+ " \"certified\":\"true\", \"age\":21}";
//Prepare in-Memory JSON Tree
JsonNode rootNode = mapper.readTree(jsonString);
//Navigate the JSON Tree through Nodes and elements structure to read data.
JsonNode firstNameNode = rootNode.path("firstName");
System.out.println("First Name ::"+firstNameNode.textValue());
JsonNode lastNameNode = rootNode.path("lastName");
System.out.println("First Name ::"+lastNameNode.textValue());
JsonNode skillNode = rootNode.path("skill");
Iterator skillItr = skillNode.elements();
System.out.println("Skills are ::");
while(skillItr.hasNext()){
JsonNode skillName = skillItr.next();
System.out.print(skillName.textValue()+" ");
}
System.out.println();
JsonNode certifiedNode = rootNode.path("certified");
System.out.println("Certified ::"+certifiedNode.booleanValue());
JsonNode ageNode = rootNode.path("age");
System.out.println("age ::"+ageNode.intValue());
}
}
Jackson provides capability to transform primitive as well as complex data types to JSON string. Here we will see List containing Map objects transformed to JSON and vice-versa.
We have simple App.java file, that contains Main method to demonstrate the capability. It has List containing Maps. Each Map holds country information.
package custom.jackson.learning;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
public class App {
public static void main(String[] args) throws Exception{
//List of country with Capital city
Map map1 = new HashMap();
map1.put("Name", "India");
map1.put("Capital", "Delhi");
map1.put("Weather", "Hot");
Map map2 = new HashMap();
map2.put("Name", "Russia");
map2.put("Capital", "Moscow");
map2.put("Weather", "Cold");
List<Map> countryList = new ArrayList<Map>();
countryList.add(map1);
countryList.add(map2);
//Convert Map to JSON
ObjectMapper mapper = new ObjectMapper();
String jsonResult = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(countryList);
System.out.println("Convert List to JSON ::"+jsonResult);
List countryList2 = mapper.readValue(jsonResult, List.class);
System.out.println("Convert JSON to List ::"+countryList2);
}
}
Output ::
As Seen in output, in first step we transform Java List to JSON. So it converts Java List into an Array of JSON Objects. In Second steps we take JSON Array as input and convert it back to Java List containing Map objects.
In this example we will see transformation of Java Map to JSON and vice-versa. JSON provides capability to map the primitive data types as well as standard collection objects. Jackson provides easy APIs to achieve it.
Jackson libraries are distributed under Apache License as open source. We will stick to Maven as build tool. These libraries are available on Maven repositories
Following dependencies, we will add into maven project POM.xml
JSON has been way of communication since long, between systems, modules or programs, especially in times of web services. JSON format has its own advantages such as ease of use, well supported by javascript and frameworks.
Hence it leads to have a framework in place that will ease out task of JSON to Java reading, writing , transformation of JSON data to Plain java objects etc. It can reduce lot of boilterplate code while dealing with JSON formatted data.
Jackson is an open source framework distributed under Apache license to address these problems. Principally, jackson has 3 approaches to address JSON to JAVA binding
Data binding APIs – It can map JSON formatted objects to Java Plain Objects(POJO). It also provides certain level of configurability to tailor the data binding.
JSON Tree – Set of APIs that would read JSON formatted input document and convert the in memory tree representation of JSON, analogous to DOM tree. Then provides APIs to deal with JSON tree.
Streaming API – Set of APIs to read input JSON streams, it is analogous to Stax API for XML parsing.
XML has been way of communication between systems, modules or programs etc. If it is the case, there is need to have framework that eases out reading from and writing to XML format and Java plain objects. It is addressed by JAXB specification.
There are multiple ways by which to and fro transformation between XML and Plain Java objects can achieved.
Using DOM Parser : This approch will read input XML stream and convert the in-memory tree representation of XML. XML DOM tree can be navigated through set of APIs
Using SAX Parser : This is event based framework to navigate through XML stream. We need to provider listener implmentation for SAX events in order to read/write XML data.
XML JAXB Annotations : Annotations can help to transform XML stream into Plain Java objects and vice-versa. Annotations are placed on properties or accessor getter methods of Plain Java classes to achieve the mapping.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>custom.validation</groupId>
<artifactId>user</artifactId>
<version>0.0.1-SNAPSHOT</version>
<description>This is hello world project for javax validation of beans</description>
<dependencies>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
</project>
2. We will write Employee class with annotations for Bean validations. Bean Validation annotations are provided by javax.validation package.
Also each annotation in general can have value to validate against, validation failure message as input parameters.
Employee.Java
package user;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class Employee {
@NotNull(message="FirstName should not be null")
private String firstName;//to demonstrate NotNull validation annotation
@NotNull(message="LastName should not be null")
private String lastName;//to demonstrate NotNull validation annotation
@AssertTrue
private boolean isCerified;//to demonstrate Boolean True validation annotation
@Size(min=10, max=200, message="Address should not exceed 200 characters or should be more than 20 characters")
private String address;//to demonstrate size validation annotation
@Min(value=18, message="Age should be more than 18")
@Max(value=61, message="Age should be less than 61")
private int age;//to demonstrate Min/Max validation annotation
@Email(message = "Should have valid email id")
private String email;//to demonstrate Email validation annotation
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public boolean isCerified() {
return isCerified;
}
public void setCerified(boolean isCerified) {
this.isCerified = isCerified;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
3. To execute programmatic validations, javax.validation package provides Validator APIs to carry out validations. Some frameworks like hibernate, we do not need to explicitly trigger validation process, as it is internally taken care of by frameworks. To trigger it explicitly, we need to use as following.