This tutorial is about serialization(convert Java object to JSON), for deserialization(convert JSON to Java object), please visit
In a RESTful Web Service, we need a library to convert the Java object to JSON as response back to the client.
In Spring, we can configure FasterXML Jackson as the library
In the application context xml, add the following:
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </mvc:message-converters> </mvc:annotation-driven>
In pom.xml, add the following dependency: (Using Gradle please see)
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.9</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.9</version> </dependency>
dependencies { implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.9' implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.9' }
Define a controller class with a @GetMapping annotated method returns a Square object:
@RestController @RequestMapping("/myapp") public class MyController { @GetMapping("/square") public Square getSquare(@RequestParam("side") int side, @RequestParam("color") String color) { Square square = new Square(); square.setArea(side * side); square.setColor(color); return square; } }
And the Square class:
public class Square { private int area; private String color; private String texture; // public setter and getter of all the fields }
After building and deployed to <CONTEXT_PATH>, by calling
curl --request GET '<CONTEXT_PATH>/myapp/square?side=12&color=blue'
will return
{ "area": 100, "color": "blue", "texture": null }
Using a different field name. If you would like the field name to be different, use the @JsonProperty annotation:
public class Square { private int area; @JsonProperty("COLOR@!") private String color; private String texture; // public setter and getter of all the fields }
Response will become:
{ "area": 100, "texture": null, "COLOR@!": "blue" }
Customize fields order. If you would like fields of the JSON object in a specific order, use the @JsonPropertyOrder annotation:
@JsonPropertyOrder({ "texture", "color", "area" }) public class Square { private int area; private String color; private String texture; // public setter and getter of all the fields }
Response will become:
{ "texture": null, "color": "blue", "area": 144 }
Exclude null fields. If you want to exclude any null field to be serialized, use @JsonInclude(JsonInclude.Include.NON_NULL) in the class:
@JsonInclude(JsonInclude.Include.NON_NULL) public class Square { private int area; private String color; private String texture; // public setter and getter of all the fields }
Response will become:
{ "area": 144, "color": "blue" }
Customizing a particular field. If you want to have complete serialization customization of a field, use JsonSerializer:
First create a class extending com.fasterxml.jackson.databind.JsonSerializer with the field data type as the generic type.
e.g. If you want to convert a String field to upper case for all the time, create a class:
e.g. If you want to convert a String field to upper case for all the time, create a class:
public class ColorSerializer extends JsonSerializer<String> { @Override public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(s.toUpperCase()); } }
Using ColorSerializer like:
public class Square { private int area; @JsonSerialize(using = ColorSerializer.class) private String color; private String texture; // public setter and getter of all the fields }
Response will become:
{ "area": 144, "color": "BLUE", "texture": null }
Fields are dynamic. If the number of fields is not fixed, instead of defining all the fields, define a map can and use @JsonAnyGetter on the getter method of the map:
public class DynamicSquare { private Map<String, String> dynamicFields; @JsonAnyGetter public Map<String, String> getDynamicFields() { return dynamicFields; } public void setDynamicFields(Map<String, String> dynamicFields) { this.dynamicFields = dynamicFields; } }
Create the DynamicSqaure as you like and return it:
@GetMapping("/dynamicSquare") public DynamicSquare getDynamicSquare(@RequestParam("side") int side, @RequestParam("color") String color) { DynamicSquare dynamicSquare = new DynamicSquare(); Map<String, String> map = new HashMap<>(); map.put("color", color); map.put("area", String.valueOf(side * side)); dynamicSquare.setDynamicFields(map); return dynamicSquare; }
Response will become:
{ "area": "144", "color": "blue" }
With one more item in the map:
@GetMapping("/dynamicSquare") public DynamicSquare getDynamicSquare(@RequestParam("side") int side, @RequestParam("color") String color) { DynamicSquare dynamicSquare = new DynamicSquare(); Map<String, String> map = new HashMap<>(); map.put("color", color); map.put("area", String.valueOf(side * side)); map.put("icon", "mouse"); dynamicSquare.setDynamicFields(map); return dynamicSquare; }
Response will become:
{ "area": "144", "color": "blue", "icon": "mouse" }