Java Json library jackson 사용법
개요
Jackson 은 자바용 json 라이브러리로 잘 알려져 있지만 Json 뿐만 아니라 XML/YAML/CSV 등 다양한 형식의 데이타를 지원하는 data-processing 툴이다.
스트림 방식이므로 속도가 빠르며 유연하며 다양한 third party 데이타 타입을 지원하며 annotation 방식으로 메타 데이타를 기술할 수 있으므로 JSON 의 약점중 하나인 문서화와 데이타 validation 문제를 해결할 수 있다.
구성
core module
- Streaming("jackson-core") : defines low-level streaming API, and includes JSON-specific implementations
- Annotations ("jackson-annotations") : contains standard Jackson annotations
- Databind ("jackson-databind") :implements data-binding (and object serialization) support on streaming package; it depends both on streaming and annotations packages
사용
maven 설정
databind 는 jackson-core, jackson-annotation 에 의존성이 있으므로 pom 파일에는 databind 모듈만 기술해주면 된다.
<properties> <jackson.version>2.11.2</jackson.version> </properties> <dependencies> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> </dependencies>
// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.11.2'
2.7 버전부터는 JDK 7 이상이 필요하며 JDK6 을 지원하는 마지막 버전은 2.6.7.1 임
POJO 와 사용
https://github.com/FasterXML/jackson-databind/
// getter/setter 를 만들지 않기 위해 public 으로 선언 // lombok 을 사용하면 간편 public class MyValue { public String name; public int age; }
com.fasterxml.jackson.databind.ObjectMapper 인스턴스 생성
ObjectMapper mapper = new ObjectMapper(); // create once, reuse
json 데이타를 java object 로 변환
{ "name": "Bob", "age": 13 }
File, URL, String 방식으로 데이타를 읽어올 수 있음.
MyValue value = mapper.readValue(new File("data.json"), MyValue.class); // URL 에서 읽기 value = mapper.readValue(new URL("http://some.com/api/entry.json"), MyValue.class); // String 으로 읽기 value = mapper.readValue("{\"name\":\"Bob\", \"age\":13}", MyValue.class);
java object 를 json 으로 변환
MyValue myResultObject = new MyValue(); myResultObject.name = "MyName"; myResultObject.age= 11; ObjectMapper mapper = new ObjectMapper(); // result.json 파일로 저장 mapper.writeValue(new File("result.json"), myResultObject); // byte[] 로 저장 byte[] jsonBytes = mapper.writeValueAsBytes(myResultObject); // string 으로 저장 String jsonString = mapper.writeValueAsString(myResultObject);
json 으로 변환시 개행하여 포맷팅
{"string":"foo","number":5,"array":[1,2,3],"object":{"property":"value","subobj":{"arr":["foo","ha"],"numero":1}}}
위와 같은 json 데이타를 다음처럼 보기 좋게 출력하려면 ObjectMapper.writerWithDefaultPrettyPrinter를 사용하면 된다.
// 포맷팅하여 스트링으로 변환 String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(myResultObject); // 포맷팅하여 파일로 저장 mapper.writerWithDefaultPrettyPrinter().writeValue(new File("output.json"), myResultObject);
Generic Collation/Tree Model 로 사용
Configurator
Annotation
@JsonIgnoreProperties
크게 2가지 용도가 있으며 첫 번째는 Serializer/Deserialize 시 제외시킬 프로퍼티를 지정한다. 다음과 같이 지정하면 foo, bar는 제외된다. 개별 프로퍼티를 제외하려면
@JsonIgnore annotation을 프로퍼티에 적용하면 된다.
@JsonIgnoreProperties({ "foo", "bar" }) public class MyBean { //아래 두 개는 제외됨. public String foo; public String bar; // will not be written as JSON; nor assigned from JSON: @JsonIgnore public String internal; // no annotation, public field is read/written normally public String external; @JsonIgnore public void setCode(int c) { _code = c; } // note: will also be ignored because setter has annotation! public int getCode() { return _code; } }
@JsonProperty
getter/setter 의 이름을 property 와 다른 이름을 사용할 수 있도록 설정한다. Database 를 자바 클래스로 매핑하는데 DB의 컬럼명이 알기 어려울 경우등에 유용하게 사용할 수 있다.
다음과 같은 테이블이 있을 경우
CREATE TABLE Users ( u INT NOT NULL, a INT NOT NULL, e VARCHAR(80) NOT NULL );
다음과 같이 JsonProperty 를 사용하면 DB 의 컬럼명을 변경하지 않아도 가독성을 높일 수 있다.
public class User { @JsonProperty("userId"); public Integer u; @JsonProperty("age"); public Integer a; @JsonProperty("email"); public String e; }
json 으로 변환된 결과
{ "userId": 1, "age": 13, "email": "user@host.com" }
@JsonInclude
Serialize 시 동작을 지정한다. 기본적으로 잭슨은 값의 유무와 상관없이 무조건 serialize 하게 되지만 다음과 같이 설정할 경우 not null 이거나 none empty 일 경우에만 serialize 된다.
public class User { public Integer u; @JsonInclude(JsonInclude.Include.NON_NULL) public Integer age; @JsonInclude(JsonInclude.Include.NON_EMPTY) public String email; }