Skip to content

Instantly share code, notes, and snippets.

@tyb
Last active July 23, 2019 04:55
Show Gist options
  • Save tyb/2fc1d7b064b508e10cc7e7fe505fd516 to your computer and use it in GitHub Desktop.
Save tyb/2fc1d7b064b508e10cc7e7fe505fd516 to your computer and use it in GitHub Desktop.
json object deserialization/unmarshalling to java object(mainly array/list) with Jackson
//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