03. JAVA/기초

11. 자바 8 (Java 8) - ObjectMapper, JsonPath, ModelMapper

THE HEYDAZE 2020. 8. 24. 08:01
OS Windows 10 Home 64bit 버전 1903 (OS 빌드 18362.836)
JAVA 8
BuildTool Gradle

 

# Book 클래스
public class Book {

    private String category;
    private String author;
    private String title;
    private String price;

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "category='" + category + '\'' +
                ", author='" + author + '\'' +
                ", title='" + title + '\'' +
                ", price='" + price + '\'' +
                '}';
    }
}

 

#1. ObjectMapper

ObjectMapper 클래스는 객체를 JSON 문자열로 직렬화, JSON 문자열을 객체로 역직렬화 한다

 

dependencies {
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8'
}

 

객체를 JSON 문자열로 변환 후 파일 생성
public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }

    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);


        Book book = new Book("나무", "베르베르 베르나르", "열린책들");
        objectMapper.writeValue(new File(path + "book.json"), book);
    }
}

 

book.json 생성

 

book.json

 

객체를 JSON 문자열로 변환 (= JSON.stringify)
public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {

        Book book = new Book("나무", "베르베르 베르나르", "열린책들");
        String jsonStringify = objectMapper.writeValueAsString(book);

        System.out.println(jsonStringify);
    }
}

결과

 

JSON 문자열을 객체에 매핑 (= JSON.parse)
public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {

        String jsonString = "{\"name\": \"나무\", \"author\": \"베르베르 베르나르\", \"publisher\": \"열린책들\"}";

        Book book = objectMapper.readValue(jsonString, Book.class);

        System.out.println(book);
    }
}

결과

 

JSON 파일을 객체에 매핑

[ File ]

public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {

        String path = getPath(Mapper.class);

        Book book = objectMapper.readValue(new File(path + "book.json"), Book.class);

        System.out.println(book);
    }
}

결과

 

[ URL ]

public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();


    public static void main(String[] args) throws IOException {

        String urlPath = "file:src/main/java/com/example/demo/chapter12/";

        Book book = objectMapper.readValue(new URL(urlPath + "book.json"), Book.class);

        System.out.println(book);
    }
}

결과

 

JSON 문자열에서 JsonNode 로 하여 필드에 접근
public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {

        String jsonString = "{\"name\": \"나무\", \"author\": \"베르베르 베르나르\", \"publisher\": \"열린책들\"}";

        JsonNode jsonNode = objectMapper.readTree(jsonString);

        String author = jsonNode.get("author").asText();

        System.out.println(author);
    }
}

결과

 

JSON 배열 문자열에서 SET 생성

[ Set ]

public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {

        String jsonBookArrayString = "[{\"name\": \"나무\", \"author\": \"베르베르 베르나르\", \"publisher\": \"열린책들\"}, {\"name\": \"어린왕자\", \"author\": \"앙투안 드 생텍쥐페리\", \"publisher\": \"갈리마르\"}]";

        Set<Book> bookSet = objectMapper.readValue(jsonBookArrayString, new TypeReference<Set<Book>>(){});

        for (Book book : bookSet) {
            System.out.println(book);
        }
    }
}

결과

 

JSON 배열 문자열에서 LIST 생성

[ List ]

public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {

        String jsonBookArrayString = "[{\"name\": \"나무\", \"author\": \"베르베르 베르나르\", \"publisher\": \"열린책들\"}, {\"name\": \"어린왕자\", \"author\": \"앙투안 드 생텍쥐페리\", \"publisher\": \"갈리마르\"}]";

        List<Book> bookList = objectMapper.readValue(jsonBookArrayString, new TypeReference<List<Book>>(){});

        for (Book book : bookList) {
            System.out.println(book);
        }
    }
}

결과

 

public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {

        String jsonString = "{\"name\": \"나무\", \"author\": \"베르베르 베르나르\", \"publisher\": \"열린책들\"}";

        Map<String, Object> bookMap = objectMapper.readValue(jsonBookArrayString, new TypeReference<Map<String, Object>>(){});

        for (String field : bookMap.keySet()) {
            System.out.println(field);
            System.out.println(bookMap.get(field));
            System.out.println();
        }
    }
}

결과

 

JSON 문자열이 객체보다 필드가 많은 경우 예외 허용
public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {

        String jsonString = "{\"overField\": \"예외발생\", \"name\": \"나무\", \"author\": \"베르베르 베르나르\", \"publisher\": \"열린책들\"}";

        // 역직렬화(객체에 parse) 시, 알수 없는 프로퍼티(필드) 에 대해서는 예외처리를 하지 않는다
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        Book book = objectMapper.readValue(jsonString, Book.class);

        System.out.println(book);

    }
}

결과

"overField": "예외발생" 에 대해서 예외가 발생하지 않는 모습

 

날짜 형식 처리 후, JSON 문자열로 변환
public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {

        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
        
        String beforeJsonStringify = objectMapper.writeValueAsString(new Date());
        System.out.println("[적용전]\n" + beforeJsonStringify + "\n");

        objectMapper.setDateFormat(format);

        String afterJsonStringify = objectMapper.writeValueAsString(new Date());
        System.out.println("[적용후]\n" + afterJsonStringify);

    }
}

결과

 

JSON 문자열에서 배열 [] 로 변환
public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {

        String jsonString = "[{\"name\": \"나무\", \"author\": \"베르베르 베르나르\", \"publisher\": \"열린책들\"}, {\"name\": \"어린왕자\", \"author\": \"앙투안 드 생텍쥐페리\", \"publisher\": \"갈리마르\"}]";

        objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
        Book[] books = objectMapper.readValue(jsonString, Book[].class);

        for (Book book : books) {
            System.out.println(book);
        }
    }
}

결과

 

사용 예시
public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {

        Book book1 = new Book("나무", "베르베르 베르나르", "열린책들");
        Book book2 = new Book("어린왕자", "앙투안 드 생텍쥐페리", "갈리마르");

        Set<Book> bookSet = new HashSet<>();
        bookSet.add(book1);
        bookSet.add(book2);

        BookStore bookStore = new BookStore("교보문고", bookSet);

        String jsonString = jsonStringify(bookStore);
        System.out.println("jsonString = " + jsonString);

        BookStore parseBookStore = jsonParse(jsonString);
        System.out.println("parseBookStore = " + parseBookStore);


    }

    private static String jsonStringify(BookStore bookStore) throws JsonProcessingException {
        System.out.println("[JSON.stringify]");
        return objectMapper.writeValueAsString(bookStore);
    }

    private static BookStore jsonParse(String jsonString) throws JsonProcessingException {
        System.out.println();
        return objectMapper.readValue(jsonString, BookStore.class);
    }
}

결과

 

#2. JsonPath

JSON 문자열에 대해서 jsonPath 를 이용하여 객체에 매핑한다

 

 

json-path/JsonPath

Java JsonPath implementation. Contribute to json-path/JsonPath development by creating an account on GitHub.

github.com

 

Jayway JsonPath evaluator

Goessner examle Twitter API Webapp 20k { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.

jsonpath.herokuapp.com

 

dependencies {
    compile group: 'com.jayway.jsonpath', name: 'json-path', version: '2.4.0'
}

 

  연산자   설명
  $   쿼리 할 루트 요소 (모든 경로 표현식)
  @   필터 술어로 처리중인 현재 노드
  *   와일드 카드 (이름이나 숫자가 필요한 모든 곳에서 사용)
  ..   이름이 필요한 모든 곳에서 사용
  .<name>   점으로 표시된 하위 프로퍼티
  ['<name>' (, '<name>')]   대괄호 표시가있는 하위 프로퍼티
  [<number> (, <number>)]   배열 인덱스 또는 인덱스
  [start:end]   배열 슬라이스 연산자
  [?(<expression>)]   필터 표현식. 표현식은 부울 값으로 평가되어야합니다.

 

  기능   설명   리턴
  min()   숫자 배열의 최소값   Double
  max()   숫자 배열의 최대값   Double
  avg()   숫자 배열의 평균값   Double
  stddev()   숫자 배열의 표준 편차 값   Double
  length()   배열의 길이   Integer
  sum()   숫자 배열의 합계   Double

 

  필터   설명
  ==   left는 right와 같음 (1은 '1'과 같지 않음)
  !=   왼쪽은 오른쪽과 같지 않습니다.
  <   왼쪽이 오른쪽보다 작습니다
  <=   왼쪽은 오른쪽보다 작거나 같습니다.
  >   왼쪽이 오른쪽보다 큽니다.
  >=   왼쪽은 오른쪽보다 크거나 같습니다.
  =~   left는 정규식 [? (@. name = ~ /foo.*?/i)]과 일치합니다.
  in   left가 오른쪽에 있음 [? (@. size in [ 'S', 'M'])]
  nin   왼쪽은 오른쪽에 존재하지 않습니다
  subsetof   left는 오른쪽의 하위 집합입니다. [? (@. sizes [ 'S', 'M', 'L'])]
  anyof   left는 right [? (@. sizes anyof [ 'M', 'L'])]와 교차합니다.
  noneof   left는 right와 교차하지 않습니다. [? (@. sizes noneof [ 'M', 'L'])]
  size   왼쪽 크기 (배열 또는 문자열)는 오른쪽과 일치해야합니다.
  empty   왼쪽 (배열 또는 문자열)은 비어 있어야합니다.

 

더보기
public class Mapper {

    public static void main(String[] args) {

        String jsonString = "{\"bookStore\": {\"book\": {\"name\": \"나무\", \"author\": \"베르베르 베르나르\", \"publisher\": \"열린책들\"}}}";

        Object all = JsonPath.read(jsonString,  "$");

        Object bookStore = JsonPath.read(jsonString,  "$.bookStore");

        Object bookAll = JsonPath.read(jsonString,  "*");

        Book book = JsonPath.parse(jsonString).read("$.bookStore.book", Book.class);


        System.out.println();
        System.out.println("[ all ]");
        System.out.println(all);

        System.out.println();
        System.out.println("[ bookStore ]");
        System.out.println(bookStore);

        System.out.println();
        System.out.println("[ bookAll ]");
        System.out.println(bookAll);


        System.out.println();
        System.out.println("[ book ]");
        System.out.println(book);
    }
}
결과

 

[ 기본 예제 ]

jsonPath.zip
0.00MB

 

{
  "store": {
    "book": [
      {
        "category": "소설",
        "author": "더글라스 케네디",
        "title": "오후의 이자벨",
        "price": 8900
      },
      {
        "category": "소설",
        "author": "앙투안 드 생택쥐페리",
        "title": "어린 왕자",
        "price": 12900
      },
      {
        "category": "소설",
        "author": "조지 오웰",
        "title": "동물농장",
        "isbn": "9788937460050(893746005X)",
        "price": 8900
      },
      {
        "category": "희곡",
        "author": "베르나르 베르베르",
        "title": "심판",
        "isbn": "9788932920405(8932920400)",
        "price": 22900
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19950
    }
  },
  "expensive": 19950
}
  $.store.book[*].author   모든 책의 저자   return List<String>
  $..author   모든 저자   return List<String>
  $.store.*   책과 서점의 모든 것   return List<String>
  $.store..price   서점의 모든 가격   return List<String>
  $..book[2]   세 번째 책   return List<String>
  $..book[-1]   마지막에서 첫 번째 책   return List<String>
  $..book[0,3]   첫 번째와 네 번째 책   return List<String>
  $..book[:2]   첫 번째부터 세 번째 미만의 책   return List<String>
  $..book[1:2]   두 번째부터 세 번째 미만의 책   return List<String>
  $..book[-2:]   마지막에서 두 번째 부터 마지막 까지의 책   return List<String>
  $..book[2:]   세 번째 부터 마지막 까지의 책   return List<String>
  $..book[?(@.isbn)]   ISBN 번호가 있는 모든 책   return List<String>
  $.store.book[?(@.price < 10000)]   서점의 책 중 10000 원 미만인 책   return List<String>
  $..book[?(@.price <= $['expensive'])]   expensive 금액 이하인 책   return List<String>
  $..book[?(@.author =~ /.*REES/i)]   정규식과 일치하는 모든 책(대소 문자 무시)   return List<String>
  $..*   모든 것   return List<String>
  $..book.length()   모든 책의 수   return List<String>
  $.store.book[0].author   서점의 첫 번째 책의 저자   return String

Java에서 JsonPath를 사용할 때 결과에서 기대하는 유형을 아는 것이 중요합니다. JsonPath는 자동으로 호출자가 예상하는 유형으로 결과를 캐스트하려고 시도합니다. - 공식 문서

definite(명확한) 경로와 indefinite(불명확한) 경로를 포함하고 있으며, indefinite(불명확한) 경로는 항상 List 타입을 반환한다 - 공식 문서

대표적으로 불명확한 연산자 

.. - 딥 스캔 여산자

?(<expression>) - 표현

[<number>, <number> (, <number>) - 여러 배열 인덱스

를 사용하는 경우 ndefinite(불명확한) 경로 인식하여 List 타입을 반환한다

 

$.store.book[*].author 
[
  "더글라스 케네디",
  "앙투안 드 생택쥐페리",
  "조지 오웰",
  "베르나르 베르베르"
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$.store.book[*].author");

        System.out.println(result);

    }
}

 

$..author
[
  "더글라스 케네디",
  "앙투안 드 생택쥐페리",
  "조지 오웰",
  "베르나르 베르베르"
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..author");

        System.out.println(result);

    }
}

 

$.store.*
[
  [
    {
      "category": "소설",
      "author": "더글라스 케네디",
      "title": "오후의 이자벨",
      "price": 8900
    },
    {
      "category": "소설",
      "author": "앙투안 드 생택쥐페리",
      "title": "어린 왕자",
      "price": 12900
    },
    {
      "category": "소설",
      "author": "조지 오웰",
      "title": "동물농장",
      "isbn": "9788937460050(893746005X)",
      "price": 8900
    },
    {
      "category": "희곡",
      "author": "베르나르 베르베르",
      "title": "심판",
      "isbn": "9788932920405(8932920400)",
      "price": 22900
    }
  ],
  {
    "color": "red",
    "price": 19950
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$.store.*");

        System.out.println(result);

    }
}

 

$.store..price
[
  8900,
  12900,
  8900,
  22900,
  19950
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$.store..price");

        System.out.println(result);

    }
}

 

$..book[2]
[
  {
    "category": "소설",
    "author": "조지 오웰",
    "title": "동물농장",
    "isbn": "9788937460050(893746005X)",
    "price": 8900
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..book[2]");

        System.out.println(result);

    }
}

 

$..book[-1]
[
  {
    "category": "희곡",
    "author": "베르나르 베르베르",
    "title": "심판",
    "isbn": "9788932920405(8932920400)",
    "price": 22900
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..book[-1]");

        System.out.println(result);

    }
}

 

$..book[0,3]
[
  {
    "category": "소설",
    "author": "더글라스 케네디",
    "title": "오후의 이자벨",
    "price": 8900
  },
  {
    "category": "희곡",
    "author": "베르나르 베르베르",
    "title": "심판",
    "isbn": "9788932920405(8932920400)",
    "price": 22900
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..book[0,3]");

        System.out.println(result);

    }
}

 

$..book[:2]
[
  {
    "category": "소설",
    "author": "더글라스 케네디",
    "title": "오후의 이자벨",
    "price": 8900
  },
  {
    "category": "소설",
    "author": "앙투안 드 생택쥐페리",
    "title": "어린 왕자",
    "price": 12900
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..book[:2]");

        System.out.println(result);

    }
}

 

$..book[1:2]
[
  {
    "category": "소설",
    "author": "앙투안 드 생택쥐페리",
    "title": "어린 왕자",
    "price": 12900
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..book[1:2]");

        System.out.println(result);

    }
}

 

$..book[-2:]
[
  {
    "category": "소설",
    "author": "조지 오웰",
    "title": "동물농장",
    "isbn": "9788937460050(893746005X)",
    "price": 8900
  },
  {
    "category": "희곡",
    "author": "베르나르 베르베르",
    "title": "심판",
    "isbn": "9788932920405(8932920400)",
    "price": 22900
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..book[-2:]");

        System.out.println(result);

    }
}

 

$..book[2:]
[
  {
    "category": "소설",
    "author": "조지 오웰",
    "title": "동물농장",
    "isbn": "9788937460050(893746005X)",
    "price": 8900
  },
  {
    "category": "희곡",
    "author": "베르나르 베르베르",
    "title": "심판",
    "isbn": "9788932920405(8932920400)",
    "price": 22900
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..book[2:]");

        System.out.println(result);

    }
}

 

$..book[? (@.isbn)]
[
  {
    "category": "소설",
    "author": "조지 오웰",
    "title": "동물농장",
    "isbn": "9788937460050(893746005X)",
    "price": 8900
  },
  {
    "category": "희곡",
    "author": "베르나르 베르베르",
    "title": "심판",
    "isbn": "9788932920405(8932920400)",
    "price": 22900
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..book[? (@.isbn)]");

        System.out.println(result);

    }
}

 

$.store.book[?(@.price<10000)]
[
  {
    "category": "소설",
    "author": "더글라스 케네디",
    "title": "오후의 이자벨",
    "price": 8900
  },
  {
    "category": "소설",
    "author": "조지 오웰",
    "title": "동물농장",
    "isbn": "9788937460050(893746005X)",
    "price": 8900
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$.store.book[?(@.price<10000)]");

        System.out.println(result);

    }
}

 

$..book[?(@.price<=$['expensive'])]
[
  {
    "category": "소설",
    "author": "더글라스 케네디",
    "title": "오후의 이자벨",
    "price": 8900
  },
  {
    "category": "소설",
    "author": "앙투안 드 생택쥐페리",
    "title": "어린 왕자",
    "price": 12900
  },
  {
    "category": "소설",
    "author": "조지 오웰",
    "title": "동물농장",
    "isbn": "9788937460050(893746005X)",
    "price": 8900
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..book[?(@.price<=$['expensive'])]");

        System.out.println(result);

    }
}

 

$..book[?(@.author=~/.*베르/i)]
[
  {
    "category": "희곡",
    "author": "베르나르 베르베르",
    "title": "심판",
    "isbn": "9788932920405(8932920400)",
    "price": 22900
  }
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..book[?(@.author=~/.*베르/i)]");

        System.out.println(result);

    }
}

 

$..*
[
  {
    "book": [
      {
        "category": "소설",
        "author": "더글라스 케네디",
        "title": "오후의 이자벨",
        "price": 8900
      },
      {
        "category": "소설",
        "author": "앙투안 드 생택쥐페리",
        "title": "어린 왕자",
        "price": 12900
      },
      {
        "category": "소설",
        "author": "조지 오웰",
        "title": "동물농장",
        "isbn": "9788937460050(893746005X)",
        "price": 8900
      },
      {
        "category": "희곡",
        "author": "베르나르 베르베르",
        "title": "심판",
        "isbn": "9788932920405(8932920400)",
        "price": 22900
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19950
    }
  },
  19950,
  [
    {
      "category": "소설",
      "author": "더글라스 케네디",
      "title": "오후의 이자벨",
      "price": 8900
    },
    {
      "category": "소설",
      "author": "앙투안 드 생택쥐페리",
      "title": "어린 왕자",
      "price": 12900
    },
    {
      "category": "소설",
      "author": "조지 오웰",
      "title": "동물농장",
      "isbn": "9788937460050(893746005X)",
      "price": 8900
    },
    {
      "category": "희곡",
      "author": "베르나르 베르베르",
      "title": "심판",
      "isbn": "9788932920405(8932920400)",
      "price": 22900
    }
  ],
  {
    "color": "red",
    "price": 19950
  },
  {
    "category": "소설",
    "author": "더글라스 케네디",
    "title": "오후의 이자벨",
    "price": 8900
  },
  {
    "category": "소설",
    "author": "앙투안 드 생택쥐페리",
    "title": "어린 왕자",
    "price": 12900
  },
  {
    "category": "소설",
    "author": "조지 오웰",
    "title": "동물농장",
    "isbn": "9788937460050(893746005X)",
    "price": 8900
  },
  {
    "category": "희곡",
    "author": "베르나르 베르베르",
    "title": "심판",
    "isbn": "9788932920405(8932920400)",
    "price": 22900
  },
  "소설",
  "더글라스 케네디",
  "오후의 이자벨",
  8900,
  "소설",
  "앙투안 드 생택쥐페리",
  "어린 왕자",
  12900,
  "소설",
  "조지 오웰",
  "동물농장",
  "9788937460050(893746005X)",
  8900,
  "희곡",
  "베르나르 베르베르",
  "심판",
  "9788932920405(8932920400)",
  22900,
  "red",
  19950
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..*");

        System.out.println(result);

    }
}

 

$..book.length()
[
  4
]
더보기
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$..book.length()");

        System.out.println(result);

    }
}

 

ObjectMapper 를 이용하여 json 파일 생성

result.json 생성

더보기
public class Mapper {

    private static ObjectMapper objectMapper = new ObjectMapper();


    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }

    private static void save(String path, Object result) throws IOException {
        objectMapper.writeValue(new File(path + "result.json"), result);

    }

    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        Object result = JsonPath.read(new File(path + "data.json"), "$.store.book[*].author");

        save(path, result);
    }
}

 

문서 읽기

[ 기본 읽기 ]

/** 정적 읽기 */
public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        List<String> result = JsonPath.read(new File(path + "data.json"),"$..author");

        System.out.println(result);

    }
}

결과

 

한 번만 읽고 싶다면 괜찮습니다. 다른 경로도 읽어야하는 경우에는 JsonPath.read (...)를 호출 할 때마다 문서가 구문 분석되므로 이것은 갈 길이 아닙니다. 문제를 피하기 위해 먼저 json을 구문 분석 할 수 있습니다. JsonPath는 또한 유창한 API를 제공합니다. 이것은 또한 가장 유연한 것입니다. - 공식 문서

public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        ReadContext ctx = JsonPath.parse(new File(path + "data.json"));

        List<String> result = ctx.read("$..author");

        System.out.println(result);

    }
}

결과

 

[ 타입 반환 ]

public class Mapper {

    private static String getPath(Class clazz) {
        String projectPath = System.getProperty("user.dir");
        String packagePath = clazz.getPackage().getName().replaceAll("[.]", "/");
        return projectPath + "/src/main/java/" + packagePath + "/";
    }


    public static void main(String[] args) throws IOException {
        String path = getPath(Mapper.class);

        List<Map<String, Object>> result = JsonPath
                                .using(Configuration.defaultConfiguration())
                                .parse(new File(path + "data.json"))
                                .read("$.store.book[?(@.price > 10)]", List.class);

        for (Map<String, Object> book : result) {
            System.out.println(book.get("author"));
        }
    }
}

결과

 

[ 날짜 변환 ]

public class Mapper {

    public static void main(String[] args) {

        String jsonString = "{\"date_as_long\" : 1411455611975}";

        Date date = JsonPath.parse(jsonString).read("$['date_as_long']", Date.class);

        System.out.println(date);
    }
}

결과

 

[ 사용자 클래스로 변환 ]

Getter 메소드와 Setter 메소드가 반드시 있어야만 한다

public class Book {

    private String category;
    private String author;
    private String title;
    private String price;

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "category='" + category + '\'' +
                ", author='" + author + '\'' +
                ", title='" + title + '\'' +
                ", price='" + price + '\'' +
                '}';
    }
}
public class Mapper {

    public static void main(String[] args) {

        String jsonString = "{\"category\": \"소설\", \"author\": \"더글라스 케네디\", \"title\": \"오후의 이자벨\", \"price\": 8900}";

        Book book = JsonPath.parse(jsonString).read("$", Book.class);

        System.out.println(book);
    }
}

결과

 

Collection 으로 변환

public class Mapper {

    public static void main(String[] args) {

        String jsonString = "{\"store\": {\"book\": [{\"category\": \"소설\", \"author\": \"더글라스 케네디\", \"title\": \"오후의 이자벨\", \"price\": 8900}, {\"category\": \"소설\", \"author\": \"앙투안 드 생택쥐페리\", \"title\": \"어린 왕자\", \"price\": 12900}, {\"category\": \"소설\", \"author\": \"조지 오웰\", \"title\": \"동물농장\", \"isbn\": \"9788937460050(893746005X)\", \"price\": 8900}, {\"category\": \"희곡\", \"author\": \"베르나르 베르베르\", \"title\": \"심판\", \"isbn\": \"9788932920405(8932920400)\", \"price\": 22900}], \"bicycle\": {\"color\": \"red\", \"price\": 19950}}, \"expensive\": 19950}";

        List<Map<String, Object>> bookStore = JsonPath.read(jsonString, "$.store.book");
        System.out.println(bookStore);
        System.out.println();

        for (Map<String, Object> book : bookStore) {
            System.out.println(book.get("author"));
        }
    }
}

결과
List<Map<String,Object>> bookStore

 

[ 제너릭 유형의 클래스로 변환 ]

public class Mapper {

    public static void main(String[] args) {

        String jsonString = "{\"store\": {\"book\": [{\"category\": \"소설\", \"author\": \"더글라스 케네디\", \"title\": \"오후의 이자벨\", \"price\": 8900}, {\"category\": \"소설\", \"author\": \"앙투안 드 생택쥐페리\", \"title\": \"어린 왕자\", \"price\": 12900}, {\"category\": \"소설\", \"author\": \"조지 오웰\", \"title\": \"동물농장\", \"isbn\": \"9788937460050(893746005X)\", \"price\": 8900}, {\"category\": \"희곡\", \"author\": \"베르나르 베르베르\", \"title\": \"심판\", \"isbn\": \"9788932920405(8932920400)\", \"price\": 22900}], \"bicycle\": {\"color\": \"red\", \"price\": 19950}}, \"expensive\": 19950}";

        List<String> titles = JsonPath.parse(jsonString).read("$.store.book[*].title", new TypeRef<List<String>>() {});

        System.out.println(titles);

    }
}

 

필터
  메소드 연산자   설명
  where(String)     프로퍼티 (필드) 지정
  and(String)     프로퍼티 (필드) 지정
  is(Object) ==   같다
  eq(Object) ==   같다
  (= equal)
  ne(Object) !=   다르다
  (= not equal)
  lt(Object) <   작다
  (= little)
  lte(Object) <=   작거나 같다
  (= little or equal)
  gt(Object) >   크다
  (= greater)
  gte(Object) >=   크거나 같다
  (= greater or equal)
  regex(Pattern)     정규식
  in(...Object)     1개 이상 같다
  nin(...Object)     1개도 같지 않다
  contains(Object)     포함한다
  subsetof(...Object)     연산자는 지정된 필드가 * 지정된 배열의 요소로 구성된 집합의 하위 집합을
  구성하는 배열 인 * 객체를 선택합니다.
  all(...Object)     모두 같다
  size(int)     프로퍼티(필드) 의 개수가 int 와 같다
  type(Class<?>)     해당 클래스와 같다 ( Date.class, List.class, Long.class )
  exists(boolean)     프로퍼티(필드) 의 존재 여부
  matches(Predicate)     프로퍼티(필드) 에서 매치

 

public class Mapper {

    public static void main(String[] args) {

        String jsonString = "{\"store\": {\"book\": [{\"category\": \"소설\", \"author\": \"더글라스 케네디\", \"title\": \"오후의 이자벨\", \"price\": 8900}, {\"category\": \"소설\", \"author\": \"앙투안 드 생택쥐페리\", \"title\": \"어린 왕자\", \"price\": 12900}, {\"category\": \"소설\", \"author\": \"조지 오웰\", \"title\": \"동물농장\", \"isbn\": \"9788937460050(893746005X)\", \"price\": 8900}, {\"category\": \"희곡\", \"author\": \"베르나르 베르베르\", \"title\": \"심판\", \"isbn\": \"9788932920405(8932920400)\", \"price\": 22900}], \"bicycle\": {\"color\": \"red\", \"price\": 19950}}, \"expensive\": 19950}";

        // JsonPath.filter, JsonPath.where, JsonPath.parse = static method
        Filter filter = filter(where("category").is("소설").and("price").lte(10000));

        List<Map<String, Object>> books = parse(jsonString).read("$.store.book[?]", filter);
        System.out.println();
        
        for (Map<String, Object> book : books) {
            System.out.println(book);
        }
    }
}

 

#3. ModelMapper

ModelMapper 클래스는 객체를 다른 객체에 매핑 해준다

 

dependencies {
    compile group: 'org.modelmapper', name: 'modelmapper', version: '2.3.0'
}

 

public class Mapper {

    public static void main(String[] args) {


        ModelMapper modelMapper = new ModelMapper();

        AccountDto accountDto = new AccountDto("admin", "root", "15", 1000L);

        Account account = modelMapper.map(accountDto, Account.class);

        System.out.println(account);

    }
}

 

B 클래스를 A 클래스에 Setter 를 이용하여 값을 넣는다

(A 클래스는 Account, B 클래스는 AccountDto)

 

public class Account {

    private String name;
    private String password;
    private String age;
    private String role;


    public void setName(String name) {
        this.name = name;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public void setRole(String role) {
        this.role = role;
    }

    @Override
    public String toString() {
        return "Account{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", age='" + age + '\'' +
                ", role='" + role + '\'' +
                '}';
    }
}

A 클래스는 기본 생성자와, Setter 메소드가 반드시 있어야 한다

 

public class AccountDto {

    private String name;
    private String password;
    private String age;
    private Long price;

    public AccountDto(String name, String password, String age, Long price) {
        this.name = name;
        this.password = password;
        this.age = age;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public String getPassword() {
        return password;
    }

    public String getAge() {
        return age;
    }

    public Long getPrice() {
        return price;
    }

    @Override
    public String toString() {
        return "AccountDto{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", age='" + age + '\'' +
                ", price=" + price +
                '}';
    }
}

B 클래스는 Getter 메소드가 반드시 있어야 한다

생성자는 처음에 값을 설정하기 위해 모든필드 생성자를 이용하였다

 

결과

AccountDto 에 있는 price 는 Account 에는 없기 때문에 없으며,

Account 에 있는 role 은 AccountDto 에 없기 때문에 null 이다

 

즉, 일치하는 필드명에 값을 설정해준다

 

필드명만 같다면 int, long, String 타입변환에 대해서는 자동으로 해준다

예를들어 Long price 1000L 같은 경우 Accout 에 String price 로 하여도 문제 없이 설정된다

Account
AccountDto
결과

price 타입이 서로 다름에도 Mapper 클래스가 타입을 변환시켜준다

 

 

타입 변환은 변환이 가능 할 때만 변환이 되기때문에 변환이 가능하지 않는 타입인 경우 exception 을 발생시킨다

Account
AccountDto
Mapper
결과