Total Pageviews

Showing posts with label jackson. Show all posts
Showing posts with label jackson. Show all posts

2018/08/13

[JSON] How to ignore Inheritance properties with Jackson

How-To
AbstractCommonEntity Superclass:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  package com.xxx.entity;
  
  
  import java.io.Serializable;
  import java.util.Date;
  
  import javax.persistence.Column;
  import javax.persistence.MappedSuperclass;
  
  import org.codehaus.jackson.annotate.JsonIgnoreProperties;
  import org.hibernate.annotations.GenerationTime;
  import org.hibernate.annotations.GeneratorType;
  import org.springframework.data.annotation.LastModifiedDate;
  
  import com.xxx.LoggedUserGenerator;
  
  import lombok.Data;
  
  @Data
  @MappedSuperclass
  public abstract class AbstractCommonEntity implements Serializable {
  
      private static final long serialVersionUID = 1L;
  
      @GeneratorType(type = LoggedUserGenerator.class, when = GenerationTime.ALWAYS)
      @Column(name = "LAST_MODIFIED_BY")
      private String lastModifiedBy;
  
      @LastModifiedDate
      @Column(name = "LAST_MODIFIED_DATETIME")
      private Date lastModifiedDatetime;
  
  }

Action subclass:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  package com.xxx.entity;
  
  import java.io.Serializable;
  
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.EntityListeners;
  import javax.persistence.GeneratedValue;
  import javax.persistence.GenerationType;
  import javax.persistence.Id;
  import javax.persistence.SequenceGenerator;
  import javax.persistence.Table;
  
  import org.springframework.data.jpa.domain.support.AuditingEntityListener;
  
  import lombok.Data;
  import lombok.EqualsAndHashCode;
  
  @Entity
  @Table(name = "ACTION")
  @Data
  @EntityListeners(AuditingEntityListener.class)
  @EqualsAndHashCode(of = "id", callSuper = false)
  public class Action extends AbstractCommonEntity implements Serializable {
  
      private static final long serialVersionUID = 1L;
      
      @Id
      @SequenceGenerator(name = "ACTION_ID_SEQ", sequenceName = "ACTION_ID_SEQ", allocationSize = 1)
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ACTION_ID_SEQ")
      @Column(name = "ID")
      private Integer id;
      
      @Column(name = "NAME")
      private String name;
      
      @Column(name = "DEPEND_SLOTS")
      private String dependSlots;
  
      @Column(name = "PROJECT_ID")
      private Integer projectId;
  
  }

If I would like to genenrate JSON from Action subclass and ignore properties from its superclass, how to do it?

How-To
Simply add @JsonIgnoreProperties in superclass:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  package com.xxx.entity;
  
  
  import java.io.Serializable;
  import java.util.Date;
  
  import javax.persistence.Column;
  import javax.persistence.MappedSuperclass;
  
  import org.codehaus.jackson.annotate.JsonIgnoreProperties;
  import org.hibernate.annotations.GenerationTime;
  import org.hibernate.annotations.GeneratorType;
  import org.springframework.data.annotation.LastModifiedDate;
  
  import com.xxx.LoggedUserGenerator;
  
  import lombok.Data;
  
  @Data
  @MappedSuperclass
  @JsonIgnoreProperties({ "lastModifiedBy", "lastModifiedDatetime" })
  public abstract class AbstractCommonEntity implements Serializable {
  
      private static final long serialVersionUID = 1L;
  
      @GeneratorType(type = LoggedUserGenerator.class, when = GenerationTime.ALWAYS)
      @Column(name = "LAST_MODIFIED_BY")
      private String lastModifiedBy;
  
      @LastModifiedDate
      @Column(name = "LAST_MODIFIED_DATETIME")
      private Date lastModifiedDatetime;
  
  }




2018/06/12

[jackson] How to define ordering when serializing object properties to JSON ?

Problem
How to define ordering when serializing object properties to JSON ?
Employ class
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
  package test.albert.jackson;
  
  import lombok.Builder;
  import lombok.Data;
  
  @Data
  @Builder
  public class Employee {
  
      private Integer id;
  
      private String name;
  
      private String email;
  
      private String phone;
  
      private Address address;
  
  }


Address class
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
  package test.albert.jackson;
  
  import lombok.Builder;
  import lombok.Data;
  
  @Data
  @Builder
  public class Address {
  
      private String streetAddress;
      private String city;
      private String zipCode;
  
  }


Using ObjectMapper to serialize object properties to JSON
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  package test.albert.jackson;
  
  import java.io.IOException;
  
  import com.fasterxml.jackson.databind.ObjectMapper;
  
  import lombok.extern.slf4j.Slf4j;
  
  @Slf4j
  public class JacksonTest {
  
      public static void main(String[] args) throws IOException {
          Address address = Address.builder().zipCode("110").city("台北市").streetAddress("信義區信義路五段7號").build();
          Employee albert = Employee.builder().id(1).name("Albert").email("albert@gmail.com").phone("0900123456")
                  .address(address).build();
          
          ObjectMapper mapper = new ObjectMapper();
          
          // convert object to JSON
          String json = mapper.writeValueAsString(albert);
          log.debug(json);
      }
  
  }


How-to
You can make good use of @JsonPropertyOrder to define the ordering, for example
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  package test.albert.jackson;
  
  import com.fasterxml.jackson.annotation.JsonPropertyOrder;
  
  import lombok.Builder;
  import lombok.Data;
  
  @Data
  @Builder
  @JsonPropertyOrder({ "id", "name", "address", "phone", "email" })
  public class Employee {
  
      private Integer id;
  
      private String name;
  
      private String email;
  
      private String phone;
  
      private Address address;
  
  }


2018/02/12

[Jackson] How to convert JSON string to YAML?

Problem
Assume I have a JSON string:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
 "id": 1,
 "name": "Albert",
 "email": "albert@gmail.com",
 "phone": "0900123456",
 "address": {
  "streetAddress": "信義區信義路五段7號",
  "city": "台北市",
  "zipCode": "110"
 }
}


I would like to convert JSON string to YAML:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 ---
id: 1
name: "Albert"
email: "albert@gmail.com"
phone: "0900123456"
address:
  streetAddress: "信義區信義路五段7號"
  city: "台北市"
  zipCode: "110"
 



How to do it?

How-To
Take advantage of libraries can fulfill this requirement.

Add the following dependencies in pom.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 <dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.9.3</version>
 </dependency>

 <dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.3</version>
 </dependency>

 <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.9.3</version>
 </dependency>

 <dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-yaml</artifactId>
  <version>2.9.3</version>
 </dependency>

Here has sample code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  package test.albert.jackson;
  
  import java.io.IOException;
  
  import com.fasterxml.jackson.databind.JsonNode;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
  
  import lombok.extern.slf4j.Slf4j;
  
  @Slf4j
  public class JacksonTest {
  
      public static void main(String[] args) throws IOException {
          Address address = Address.builder().zipCode("110").city("台北市").streetAddress("信義區信義路五段7號").build();
          Employee albert = Employee.builder().id(1).name("Albert").email("albert@gmail.com").phone("0900123456")
                  .address(address).build();
  
          
          ObjectMapper mapper = new ObjectMapper();
          
          // convert object to JSON
          String json = mapper.writeValueAsString(albert);
          log.debug(json);
          
          // convert JSON to YAML
          JsonNode jsonNode = mapper.readTree(json);
          String yaml = new YAMLMapper().writeValueAsString(jsonNode);
          log.debug("yaml = \n " + yaml);
      }
  
  }



2018/01/12

[JSON] Jackson Annotations for JSON

Assume I have two Java beans:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
  package test.albert.jackson;
    
  import lombok.Builder;
  import lombok.Data;
    
  @Data
  @Builder
  public class Employee {
    
      private Integer id;
    
      private String name;
    
      private String email;
    
      private String phone;
        
      private Address address;
   
  }


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
  package test.albert.jackson;
    
  import lombok.Builder;
  import lombok.Data;
    
  @Data
  @Builder
  public class Address {
    
      private String streetAddress;
      private String city;
      private String zipCode;
    
  }
    


I am using ObjectMapper to convert object into JSON string, the example code is as bellows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
  package test.albert.jackson;
    
  import com.fasterxml.jackson.core.JsonProcessingException;
  import com.fasterxml.jackson.databind.ObjectMapper;
    
  import lombok.extern.slf4j.Slf4j;
    
  @Slf4j
  public class JacksonTest {
    
      public static void main(String[] args) throws JsonProcessingException {
          Address address = Address.builder().zipCode("110").city("台北市").streetAddress("信義區信義路五段7號").build();
          Employee albert = Employee.builder().id(1).name("Albert").email("albert@gmail.com").phone("0900123456")
                  .address(address).build();
    
          ObjectMapper mapper = new ObjectMapper();
          String json = mapper.writeValueAsString(albert);
          log.debug(json);
      }
    
  }
    

The generated JSON looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
 "id": 1,
 "name": "Albert",
 "email": "albert@gmail.com",
 "phone": "0900123456",
 "address": {
  "streetAddress": "信義區信義路五段7號",
  "city": "台北市",
  "zipCode": "110"
 }
}


If I would like to ignore id, just add @JsonIgnore to id



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
  package test.albert.jackson;
  
  import lombok.Builder;
  import lombok.Data;
  
  @Data
  @Builder
  public class Employee {
  
      @JsonIgnore
      private Integer id;
  
      private String name;
  
      private String email;
  
      private String phone;
  
      private Address address;
  
  }

If I would like to get rid of id and phone in Employee, add 
@JsonIgnoreProperties({"id", "phone"}) to Employee class:



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  package test.albert.jackson;
  
  import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
  
  import lombok.Builder;
  import lombok.Data;
  
  @Data
  @Builder
  @JsonIgnoreProperties({"id", "phone"})
  public class Employee {
  
      private Integer id;
  
      private String name;
  
      private String email;
  
      private String phone;
  
      private Address address;
  
  }


If I want to remove address from Employee class, just add @JsonIgnoreType to Address class.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
  package test.albert.jackson;
  
  import com.fasterxml.jackson.annotation.JsonIgnoreType;
  
  import lombok.Builder;
  import lombok.Data;
  
  @Data
  @Builder
  @JsonIgnoreType
  public class Address {
  
      private String streetAddress;
      private String city;
      private String zipCode;
  
  }

2017/12/04

Illegal unquoted character ((CTRL-CHAR, code 26)): has to be escaped using backslash to be included in string.

Problem
When I try to convert JSON string to Java bean via Jackson Framework, it throws an exception as bellows: 
Illegal unquoted character ((CTRL-CHAR, code 26)): has to be escaped using backslash to be included in string.

The code snippet is:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package albert.practice.json;

import java.io.IOException;

import org.codehaus.jackson.JsonParser.Feature;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.ObjectMapper;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

public class JSONUtils {

    public Response convertJsonToObject(String json) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        Response response = null;
        try {
            response = mapper.readValue(json, Response.class);
        } catch (IOException e) {
            throw e;
        }
        return response;
    }

    @Data
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Response {
        @JsonProperty("Type")
        private String type;
        @JsonProperty("Status")
        private String status;
    }
}




How-To
Owing to the JSON has some CTRL-CHAR, so Jackson Framework cannot covert to Java bean correctly. 
You need to configure OjbectMapper to accept backslash escaping character. The updated code snippet looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package albert.practice.json;

import java.io.IOException;

import org.codehaus.jackson.JsonParser.Feature;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.ObjectMapper;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

public class JSONUtils {

    public Response convertJsonToObject(String json) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);
        Response response = null;
        try {
            response = mapper.readValue(json, Response.class);
        } catch (IOException e) {
            throw e;
        }
        return response;
    }

    @Data
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Response {
        @JsonProperty("Type")
        private String type;
        @JsonProperty("Status")
        private String status;
    }
}





2017/03/04

[jackson] How to rename JSON attribute name

Problem
I would like to create a Java Bean to do mapping with JSON object.
But the JSON object has an attribute name, public, which has conflict with Java, because public is an reserved word in Java. How to handle this problem?



How-to
You can utilize @JsonProperty to rename it.
The Java bean looks like (publicStr is mapping to public in JSON):
    @Data
    @ToString
    public static class DsnDto {
        @JsonProperty("public")
        private String publicStr;
        private String secret;
        private String csp;
    }


Reference
[1] https://stackoverflow.com/questions/9741134/jackson-annotation-how-to-rename-element-names

2016/09/03

[jackson] How to generate json from java bean and vice versa

Problem
If I would like to do conversation with Java Bean to JSON and JSON to Java Bean, any library can be used?

How-To
Add dependency to your pom.xml
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

Create an User bean for test:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package albert.practice.json;

import java.io.Serializable;

import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    private String id;
    private String login;
    private String mail;
}

Test code is as bellows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package albert.practice.json;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class JacksonTest {

    public static void main(String[] args) {
        JacksonTest test = new JacksonTest();
        String jsonString = test.convertOjbectToJson();

        List<User> users = test.convertJsonToObject(jsonString);
        for (User user : users) {
           log.debug("user = " + user.toString());
        }
    }

    public List<User> convertJsonToObject(String jsonString) {
        ObjectMapper mapper = new ObjectMapper();
        List<User> users = new ArrayList<User>();
        try {
            users = mapper.readValue(jsonString, new TypeReference<List<User>>() {
        });
    } catch (JsonParseException e) {
        e.printStackTrace();
    } catch (JsonMappingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
        return users;
    }

    public String convertOjbectToJson() {
        List<User> users = createUsers();
        String jsonString = "";

        ObjectMapper mapper = new ObjectMapper();

        try {
            jsonString = mapper.writeValueAsString(users);
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.debug("jsonString = " + jsonString);
        return jsonString;
    }

    private List<User> createUsers() {
        User albert = new User();
        albert.setId("1");
        albert.setLogin("albert");
        albert.setMail("albert@gmail.com");

        User mandy = new User();
        mandy.setId("2");
        mandy.setLogin("mandy");
        mandy.setMail("mandy@gmail.com");

        User verio = new User();
        verio.setId("3");
        verio.setLogin("verio");
        verio.setMail("verio@gmail.com");

        List<User> users = new ArrayList<User>();
        users.add(albert);
        users.add(mandy);
        users.add(verio);

        return users;
    }

}

print log:
1
2
3
4
2016-06-01 15:35:39.630 [main] DEBUG albert.practice.json.JacksonTest - jsonString = [{"id":"1","login":"albert","mail":"albert@gmail.com"},{"id":"2","login":"mandy","mail":"mandy@gmail.com"},{"id":"3","login":"verio","mail":"verio@gmail.com"}]
2016-06-01 15:35:39.670 [main] DEBUG albert.practice.json.JacksonTest - user = User(id=1, login=albert, mail=albert@gmail.com)
2016-06-01 15:35:39.670 [main] DEBUG albert.practice.json.JacksonTest - user = User(id=2, login=mandy, mail=mandy@gmail.com)
2016-06-01 15:35:39.670 [main] DEBUG albert.practice.json.JacksonTest - user = User(id=3, login=verio, mail=verio@gmail.com)

Reference
[1] http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
[2] https://stackoverflow.com/questions/28821715/java-lang-classcastexception-java-util-linkedhashmap-cannot-be-cast-to-com-test