Last active
July 23, 2019 04:55
-
-
Save tyb/2fc1d7b064b508e10cc7e7fe505fd516 to your computer and use it in GitHub Desktop.
json object deserialization/unmarshalling to java object(mainly array/list) with Jackson
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//jackson mapper.readValue - json to java object | |
@RequestMapping(value="/newPost", method = RequestMethod.POST, produces="application/json", consumes = "application/json") | |
@ResponseBody | |
public ResponseEntity newPost(@RequestBody String body) throws Exception { | |
ObjectMapper mapper = new ObjectMapper(); | |
TypeReference<HashMap<String,Object>> typeRef = new TypeReference<HashMap<String,Object>>() {}; | |
HashMap<String,Object> map = mapper.readValue(body, typeRef); | |
} | |
//jackson - json to object | |
ObjectMapper mapper = new ObjectMapper(); | |
//JSON file to Java object | |
Staff obj = mapper.readValue(new File("c:\\test\\staff.json"), Staff.class); | |
//JSON URL to Java object | |
Staff obj = mapper.readValue(new URL("http://some-domains/api/name.json"), Staff.class); | |
//JSON string to Java Object | |
Staff obj = mapper.readValue("{'name' : 'mkyong'}", Staff.class); | |
//jackson serializing/marshalling - java object to json | |
ObjectMapper mapper = new ObjectMapper(); | |
// Java object to JSON file | |
mapper.writeValue(new File("c:\\test\\staff.json"), new Staff()); | |
// Java object to JSON string | |
String jsonString = mapper.writeValueAsString(object); | |
//pretty print | |
String jsonInString2 = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(staff); | |
//setting an object | |
private static Staff createStaff() { | |
Staff staff = new Staff(); | |
staff.setName("mkyong"); | |
staff.setAge(38); | |
staff.setPosition(new String[]{"Founder", "CTO", "Writer"}); | |
Map<String, BigDecimal> salary = new HashMap() {{ | |
put("2010", new BigDecimal(10000)); | |
put("2012", new BigDecimal(12000)); | |
put("2018", new BigDecimal(14000)); | |
}}; | |
staff.setSalary(salary); | |
staff.setSkills(Arrays.asList("java", "python", "node", "kotlin")); | |
return staff; | |
} | |
//a JSON can be parsed into a JsonNode object and used to retrieve data from a specific node: | |
String json = "{ \"color\" : \"Black\", \"type\" : \"FIAT\" }"; | |
JsonNode jsonNode = objectMapper.readTree(json); | |
String color = jsonNode.get("color").asText(); | |
// Output: color -> Black | |
//customizable serialization and deserialization process. | |
//custom serializer | |
public class CustomCarSerializer extends StdSerializer<Car> { | |
public CustomCarSerializer() { | |
this(null); | |
} | |
public CustomCarSerializer(Class<Car> t) { | |
super(t); | |
} | |
@Override | |
public void serialize( | |
Car car, JsonGenerator jsonGenerator, SerializerProvider serializer) { | |
jsonGenerator.writeStartObject(); | |
jsonGenerator.writeStringField("car_brand", car.getType()); | |
jsonGenerator.writeEndObject(); | |
} | |
} | |
//invocation | |
ObjectMapper mapper = new ObjectMapper(); | |
SimpleModule module = new SimpleModule("CustomCarSerializer", new Version(1, 0, 0, null, null, null)); | |
module.addSerializer(Car.class, new CustomCarSerializer()); | |
mapper.registerModule(module); | |
Car car = new Car("yellow", "renault"); | |
String carJson = mapper.writeValueAsString(car); | |
//custom deserializer | |
public class CustomCarDeserializer extends StdDeserializer<Car> { | |
public CustomCarDeserializer() { | |
this(null); | |
} | |
public CustomCarDeserializer(Class<?> vc) { | |
super(vc); | |
} | |
@Override | |
public Car deserialize(JsonParser parser, DeserializationContext deserializer) { | |
Car car = new Car(); | |
ObjectCodec codec = parser.getCodec(); | |
JsonNode node = codec.readTree(parser); | |
// try catch block | |
JsonNode colorNode = node.get("color"); | |
String color = colorNode.asText(); | |
car.setColor(color); | |
return car; | |
} | |
} | |
//invocation | |
String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }"; | |
ObjectMapper mapper = new ObjectMapper(); | |
SimpleModule module = | |
new SimpleModule("CustomCarDeserializer", new Version(1, 0, 0, null, null, null)); | |
module.addDeserializer(Car.class, new CustomCarDeserializer()); | |
mapper.registerModule(module); | |
Car car = mapper.readValue(json, Car.class); | |
//handle data formats | |
ObjectMapper objectMapper = new ObjectMapper(); | |
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z"); | |
objectMapper.setDateFormat(df); | |
String carAsString = objectMapper.writeValueAsString(request); | |
// output: {"car":{"color":"yellow","type":"renault"},"datePurchased":"2016-07-03 11:43 AM CEST"} | |
//handle dynamic JSON objects, which have unknown properties | |
class Product { | |
// common fields | |
JsonNode details; | |
// standard getters and setters | |
} | |
//invocation | |
String json = "<json object>"; | |
Product product = objectMapper.readValue(json, Product.class); | |
assertThat(product.getName()).isEqualTo("Pear yPhone 72"); | |
assertThat(product.getDetails().get("audioConnector").asText()).isEqualTo("none"); | |
//or without jackson dependency in pojo | |
class Product { | |
// common fields | |
Map<String, Object> details; | |
// standard getters and setters | |
} | |
//when having fixed and dynamic properties mixed in a single JSON object | |
class Product { | |
// common fields | |
Map<String, Object> details = new LinkedHashMap<>(); | |
@JsonAnySetter | |
void setDetail(String key, Object value) { | |
details.put(key, value); | |
} | |
// standard getters and setters | |
} | |
//@RequestBody Spring MVC annotation to deserialize/un-marshall JSON string to Java object | |
@RestController | |
public class CustomerController { | |
//@Autowired CustomerService customerService; | |
@RequestMapping(path="/customers", method= RequestMethod.POST) | |
@ResponseStatus(HttpStatus.CREATED) | |
public Customer postCustomer(@RequestBody Customer customer){ | |
//return customerService.createCustomer(customer); | |
} | |
} | |
//BU GEREKLİ Mİ? - Annotate your entities member elements with @JsonProperty with corresponding json field names. | |
public class Customer { | |
@JsonProperty("customer_id") | |
private long customerId; | |
@JsonProperty("first_name") | |
private String firstName; | |
@JsonProperty("last_name") | |
private String lastName; | |
@JsonProperty("town") | |
private String town; | |
} | |
//if your objects have some common properties, as well as some optional ones | |
@JsonIgnore | |
private Map<String, Object> additionalProperties = new HashMap<String, Object>(); | |
@JsonAnyGetter | |
public Map<String, Object> getAdditionalProperties() { | |
return this.additionalProperties; | |
} | |
@JsonAnySetter | |
public void setAdditionalProperty(String name, Object value) { | |
this.additionalProperties.put(name, value); | |
} | |
//The way I understand it, your objects have some common properties, as well as some optional ones. You can model the optional properties using @JsonAnyGetter and @JsonAnySetter: | |
class Data { | |
@JsonProperty | |
private Long created; | |
@JsonProperty | |
private String id; | |
@JsonProperty | |
private String type; | |
private Map<String, Object> optional = new HashMap<>(); | |
public Data() { // empty public constructor is required | |
} | |
// getters/setters for all properties omitted for brevity | |
@JsonAnySetter | |
public void addOptional(String name, Object value) { | |
optional.put(name, value); | |
} | |
@JsonAnyGetter | |
public Object getOptional(String name) { | |
return optional.get(name); | |
} | |
} | |
//Then you can deserialize your objects using | |
ObjectMapper objectMapper = new ObjectMapper(); | |
Data data = objectMapper.readValue(j, Data.class); | |
//or, if you've got an array of your Data objects as input, | |
Data[] data = objectMapper.readValue(j, Data[].class); | |
//All properties except created, id and type will be placed in the optional map. | |
//creating a custom pojo | |
package com.stackoverflow.question; | |
import com.fasterxml.jackson.annotation.*; | |
import java.util.HashMap; | |
import java.util.Map; | |
@JsonInclude(JsonInclude.Include.NON_NULL) | |
@JsonPropertyOrder({ | |
"userId", | |
"postBody", | |
"postTitle", | |
"created", | |
"tagList" | |
}) | |
public class MyRequest { | |
@JsonProperty("userId") | |
private int userId; | |
@JsonProperty("postBody") | |
private String postBody; | |
@JsonProperty("postTitle") | |
private String postTitle; | |
@JsonProperty("created") | |
private Object created; | |
@JsonProperty("tagList") | |
private String[] tagList = null; | |
@JsonIgnore | |
private Map<String, Object> additionalProperties = new HashMap<String, Object>(); | |
@JsonProperty("userId") | |
public int getUserId() { | |
return userId; | |
} | |
@JsonProperty("userId") | |
public void setUserId(int userId) { | |
this.userId = userId; | |
} | |
@JsonProperty("postBody") | |
public String getPostBody() { | |
return postBody; | |
} | |
@JsonProperty("postBody") | |
public void setPostBody(String postBody) { | |
this.postBody = postBody; | |
} | |
@JsonProperty("postTitle") | |
public String getPostTitle() { | |
return postTitle; | |
} | |
@JsonProperty("postTitle") | |
public void setPostTitle(String postTitle) { | |
this.postTitle = postTitle; | |
} | |
@JsonProperty("created") | |
public Object getCreated() { | |
return created; | |
} | |
@JsonProperty("created") | |
public void setCreated(Object created) { | |
this.created = created; | |
} | |
@JsonProperty("tagList") | |
public String[] getTagList() { | |
return tagList; | |
} | |
@JsonProperty("tagList") | |
public void setTagList(String[] tagList) { | |
this.tagList = tagList; | |
} | |
@JsonAnyGetter | |
public Map<String, Object> getAdditionalProperties() { | |
return this.additionalProperties; | |
} | |
@JsonAnySetter | |
public void setAdditionalProperty(String name, Object value) { | |
this.additionalProperties.put(name, value); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment