자바 중 잭 슨 빠 른 입문

19034 단어 Jackson입문 하 다
자바 생태 권 에는 JSON 과 XML 포맷 을 처리 하 는 라 이브 러 리 가 많 으 며 잭 슨 은 그 중에서 도 유명 하 다.JDK 는 XML 처리 라 이브 러 리 를 자체 가지 고 있 지만 상대 적 으로 저급 하기 때문에 본 고 에서 소개 한 Jackson 등 고급 라 이브 러 리 로 처리 하 는 것 이 훨씬 편리 하 다.
라 이브 러 리 도입
Jackson 관련 라 이브 러 리 는 기능 에 따라 몇 개의 상대 적 으로 독립 된 것 으로 나 뉘 기 때문에 여러 개의 라 이브 러 리 를 동시에 도입 해 야 합 니 다.제 가 버 전 번 호 를 따로 추출 하여 설정 할 수 있 도록 관련 Gradle 설정 은 다음 과 같 습 니 다.

ext {
  jacksonVersion = '2.9.5'
}

dependencies {
  compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: jacksonVersion
  compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jacksonVersion
  compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: jacksonVersion
  //   XML  
  compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: jacksonVersion
  //  JDK  XML        
  compile group: 'com.fasterxml.woodstox', name: 'woodstox-core', version: '5.1.0'
  // Java 8    
  compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: jacksonVersion
  compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-parameter-names', version: jacksonVersion
  compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version: jacksonVersion

  compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.16.22'
}

Maven 설정mvnrepository에서 검색 하 세 요.
잭 슨 주해
Jackson 라 이브 러 리 에는 자바 류 와 JSON 간 의 관 계 를 신속하게 구축 할 수 있 는 많은 주석 이 포함 되 어 있다.자세 한 문 서 는 Jackson-annotations 를 참고 할 수 있 습 니 다.자주 쓰 는 것 을 소개 하 겠 습 니 다.
속성 이름
@JSonProperty 주 해 는 JSON 맵 에 사용 할 속성 을 지정 합 니 다.기본적으로 맵 의 JSON 속성 은 주해 의 속성 이름과 같 지만 이 주해 의 value 값 을 사용 하여 JSON 속성 명 을 수정 할 수 있 습 니 다.이 주 해 는 JSON 속성 을 생 성 하 는 순 서 를 지정 합 니 다.필요 하 다 면.
속성 포함
JSON 을 매 핑 할 때 어떤 속성 을 포함 하거나 제거 하 는 것 을 관리 할 수 있 는 주해 도 있 습 니 다.다음은 자주 사용 하 는 몇 가 지 를 소개 합 니 다.
@JSonIgnore 주 해 는 특정한 속성 을 제거 하 는 데 사 용 됩 니 다.그러면 이 속성 은 Jackson 의 직렬 화 와 반 직렬 화 되 지 않 습 니 다.
@JSONIgnore Properties 주 해 는 클래스 주해 입 니 다.JSON 으로 서열 화 될 때@JSonIgnoreProperties({"prop 1","prop 2"})는 프로 1 과 프로 2 두 속성 을 무시 합 니 다.JSON 에서 자바 클래스 로 반 직렬 화 될 때@JSonIgnoreProperties(ignore Unknown=true)는 Getter 와 Setter 가 없 는 모든 속성 을 무시 합 니 다.이 주 해 는 자바 류 가 JSON 과 완전히 일치 하지 않 을 때 유용 하 다.
@JSONIgnoreType 도 클래스 주석 으로 지정 한 모든 종류의 속성 을 제거 합 니 다.
직렬 화 상관
@JSonPropertyOrder 는@JSonProperty 의 index 속성 과 유사 하 며 속성 서열 화 순 서 를 지정 합 니 다.
@JSonRootName 주 해 는 JSON 루트 속성의 이름 을 지정 하 는 데 사 용 됩 니 다.
JSON 처리
단순 매 핑
우 리 는 Lombok 으로 간단 한 자바 류 를 설정 합 니 다.

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Friend {
  private String nickname;
  private int age;
}

그리고 JSON 데 이 터 를 처리 할 수 있 습 니 다.우선 Object Mapper 대상 이 필요 합 니 다.직렬 화 와 반 직렬 화 는 모두 필요 합 니 다.

    ObjectMapper mapper = new ObjectMapper();
    Friend friend = new Friend("yitian", 25);

    //      
    String text = mapper.writeValueAsString(friend);
    //     
    mapper.writeValue(new File("friend.json"), friend);
    //      
    byte[] bytes = mapper.writeValueAsBytes(friend);
    System.out.println(text);
    //        
    Friend newFriend = mapper.readValue(text, Friend.class);
    //        
    newFriend = mapper.readValue(bytes, Friend.class);
    //       
    newFriend = mapper.readValue(new File("friend.json"), Friend.class);
    System.out.println(newFriend);

프로그램 결 과 는 다음 과 같다.생 성 된 JSON 속성 과 자바 클래스 의 정의 가 일치 하 는 것 을 볼 수 있 습 니 다.

{"nickname":"yitian","age":25}
Friend(nickname=yitian, age=25)
집합 맵
자바 클래스 를 사용 하여 매 핑 하 는 것 외 에 맵 과 List 등 자바 집합 조직 JSON 데 이 터 를 직접 사용 할 수 있 으 며 필요 할 때 readTree 방법 으로 JSON 의 특정한 속성 값 을 직접 읽 을 수 있 습 니 다.주의해 야 할 것 은 JSON 에서 Map 대상 으로 전환 할 때 자바 의 형식 이 지 워 지기 때문에 형식 은 new TypeReference로 수 동 으로 제시 해 야 합 니 다.

    ObjectMapper mapper = new ObjectMapper();

    Map<String, Object> map = new HashMap<>();
    map.put("age", 25);
    map.put("name", "yitian");
    map.put("interests", new String[]{"pc games", "music"});

    String text = mapper.writeValueAsString(map);
    System.out.println(text);

    Map<String, Object> map2 = mapper.readValue(text, new TypeReference<Map<String, Object>>() {
    });
    System.out.println(map2);

    JsonNode root = mapper.readTree(text);
    String name = root.get("name").asText();
    int age = root.get("age").asInt();

    System.out.println("name:" + name + " age:" + age);

프로그램 결 과 는 다음 과 같다.
{"name":"yitian","interests":["pc games","music"],"age":25}
{name=yitian, interests=[pc games, music], age=25}
name:yitian age:25
Jackson 설정
Jackson 은 일부 설정 을 미리 정 의 했 습 니 다.일부 속성 을 사용 하거나 사용 하지 않 으 면 Jackson 이 실행 하 는 행동 을 수정 할 수 있 습 니 다.자세 한 문 서 는 Jackson Features 참조.다음은 잭 슨 README 에 열 거 된 속성 들 을 간단하게 번역 해 보 겠 습 니 다.

//     
mapper.enable(SerializationFeature.INDENT_OUTPUT);
//        POJO 
// (       )
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
//  java.util.Date, Calendar     (   )
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

//                
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
//   JSON     ("")   null   :
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

//  JSON   C/C++      (   ,    )
mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
//           (   )
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
//      (   )
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
//      ASCII  
mapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
//         JSON  ,    @JsonRootName    
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);

여기에 세 가지 방법 이 있 습 니 다.configure 방법 은 설정 이름과 설정 할 값 을 받 아들 이 고 Jackson 2.5 버 전에 새로 추 가 된 enable 과 disable 방법 은 해당 속성 을 직접 사용 하고 사용 하지 않 습 니 다.저 는 다음 두 가지 방법 을 추천 합 니 다.
주해 로 맵 관리
앞에서 잭 슨 주 해 를 소 개 했 는데,다음은 이 주 해 를 응용 해 보 겠 습 니 다.우선 주 해 를 사용 한 자바 류 를 살 펴 보 자.

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonRootName("FriendDetail")
@JsonIgnoreProperties({"uselessProp1", "uselessProp3"})
public class FriendDetail {
  @JsonProperty("NickName")
  private String name;
  @JsonProperty("Age")
  private int age;
  private String uselessProp1;
  @JsonIgnore
  private int uselessProp2;
  private String uselessProp3;
}

그리고 코드 좀 봐.주의해 야 할 것 은 제 외 된 속성 이 설정 되 어 있 기 때문에 생 성 된 JSON 과 자바 클래스 가 완전히 대응 하 는 관계 가 아니 므 로 DeserializationFeature.FAIL 을 사용 하지 않 습 니 다.ON_UNKNOWN_PROPERTIES 는 필요 합 니 다.

    ObjectMapper mapper = new ObjectMapper();
    //mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    FriendDetail fd = new FriendDetail("yitian", 25, "", 0, "");
    String text = mapper.writeValueAsString(fd);
    System.out.println(text);

    FriendDetail fd2 = mapper.readValue(text, FriendDetail.class);
    System.out.println(fd2);

운행 결 과 는 다음 과 같다.JSON 을 생 성 할 때 우리 가 만 든 값 을 무시 하고 자바 클래스 로 변환 할 때 대응 하 는 속성 이 비어 있 는 것 을 볼 수 있 습 니 다.
{"NickName":"yitian","Age":25}
FriendDetail(name=yitian, age=25, uselessProp1=null, uselessProp2=0, uselessProp3=null)
그리고 주석 코드 에 있 는 줄 을 취소 합 니 다.즉,WRAP 를 사용 합 니 다.ROOT_VALUE 기능,프로그램 을 다시 실행 합 니 다.실행 결 과 는 다음 과 같 습 니 다.생 성 된 JSON 결과 가 바 뀌 었 고 JSON 결과 가 바 뀌 었 기 때문에 자바 클래스 변환 이 실 패 했 습 니 다(모든 필드 값 이 비어 있 음).WRAP_ROOT_VALUE 라 는 기능 은 어떤 때 는 JSON 파일 이 이런 구 조 를 필요 로 하기 때문에 비교적 유용 하 다.
{"FriendDetail":{"NickName":"yitian","Age":25}}
FriendDetail(name=null, age=0, uselessProp1=null, uselessProp2=0, uselessProp3=null)
자바 8 날짜 시간 클래스 지원
자바 8 은 새로운 날짜 시간 류 를 추 가 했 고 잭 슨 도 이에 대해 지지 했다.이러한 지원 은 Jackson 모듈 형식 으로 제공 되 기 때문에 먼저 이 모듈 을 등록 하 는 것 입 니 다.

    ObjectMapper mapper = new ObjectMapper()
        .registerModule(new JavaTimeModule())
        .registerModule(new ParameterNamesModule())
        .registerModule(new Jdk8Module());

라 이브 러 리 를 가 져 오 면 Jackson 도 모든 모듈 을 자동 으로 검색 할 수 있 습 니 다.수 동 으로 등록 할 필요 가 없습니다.

mapper.findAndRegisterModules();
LocalDate 필드 가 있 는 자바 클래스 를 새로 만 듭 니 다.

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonRootName("Person")
public class Person {
  @JsonProperty("Name")
  private String name;
  @JsonProperty("NickName")
  private String nickname;
  @JsonProperty("Age")
  private int age;
  @JsonProperty("IdentityCode")
  private String identityCode;
  @JsonProperty
  @JsonFormat(pattern = "yyyy-MM-DD")
  private LocalDate birthday;

}

그리고 코드 를 보 겠 습 니 다.

  static void java8DateTime() throws IOException {
    Person p1 = new Person("yitian", "  ", 25, "10000", LocalDate.of(1994, 1, 1));
    ObjectMapper mapper = new ObjectMapper()
        .registerModule(new JavaTimeModule());
    //mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    String text = mapper.writeValueAsString(p1);
    System.out.println(text);

    Person p2 = mapper.readValue(text, Person.class);
    System.out.println(p2);
  }

운행 결 과 는 다음 과 같다.생 성 된 JSON 날짜 가[1994,1,1]과 같은 타임 스탬프 형식 으로 바 뀌 었 음 을 알 수 있 으 며,일반적으로 우리 의 요구 에 부합 되 지 않 는 다.
{"birthday":[1994,1,1],"Name":"yitian","NickName":"이 천","Age":25,"IdentityCode":"10000"}
Person(name=yitian,nickname=이 천,age=25,identityCode=10000,birthday=1994-01-01)
주석 을 취소 하 십시오.프로그램 실행 결 과 는 다음 과 같 습 니 다.이렇게 되면 우리 가 일반적으로 사용 하 는 형식 이 된다.포맷 이 필요 하 다 면@JSonFormat(pattern="yyy-MM-DD")주석 으로 포맷 날 짜 를 표시 할 수 있 습 니 다.
{"birthday":"1994-01-01","Name":"yitian","NickName":"이 천","나이":25,"IdentityCode":"10000"}
Person(name=yitian,nickname=이 천,age=25,identityCode=10000,birthday=1994-01-01)
XML 처리
잭 슨 은 JSON 을 처리 하 는 라 이브 러 리 이지 만 잭 슨-dataformat-xml 패 키 지 를 통 해 XML 을 처리 하 는 기능 을 제공 합 니 다.Jackson 은 XML 을 처리 할 때 Woodstox-core 가방 을 사용 하 라 고 제안 했다.이것 은 XML 의 실현 으로 JDK 자체 XML 보다 더욱 효율 적 이 고 안전 하 다.
자바 9 이상 의 JDK 를 사용 하고 있다 면 자바.lang.NoClassDef Foundation Error:자바 x/xml/bid/JAXB Exception 이상 이 발생 할 수 있 습 니 다.자바 9 가 JDK 의 모듈 화 를 실현 하고 JDK 와 함께 포 장 된 JAXB 를 분리 하기 때 문 입 니 다.그래서 이 럴 때 는 우리 가 수 동 으로 JAXB 의 실현 을 추가 해 야 한다.Gradle 에 아래 코드 를 추가 하면 됩 니 다.

compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'
주해
잭 슨 XML 은 잭 슨 JSON 과 JDK JAXB 의 일부 주 해 를 사용 하 는 것 외 에 자신 도 일부 주 해 를 정의 했다.다음은 몇 가지 상용 주 해 를 간단하게 소개 하 겠 습 니 다.
@JacksonXmlProperty 주 해 는 세 가지 속성 이 있 습 니 다.namespace 와 localname 속성 은 XML 네 임 스페이스 의 이름 을 지정 하 는 데 사 용 됩 니 다.isAttribute 는 이 속성 을 XML 의 속성()으로 지정 합 니까?아니면 하위 탭()으로 지정 합 니까?
@JacksonXmlRootElement 주 해 는 두 가지 속성 이 있 습 니 다.namespace 와 localname 속성 은 XML 루트 요소 네 임 스페이스 의 이름 을 지정 하 는 데 사 용 됩 니 다.
@JacksonXmlText 주 해 는 탭 에 패키지 되 지 않 은 일반 텍스트 로 속성 을 직접 표시 합 니 다.
@JacksonXmlCData 는 CDATA 탭 에 속성 을 감 싸 줍 니 다.
XML 매 핑
다음 자바 클래스 를 새로 만 듭 니 다.

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonRootName("Person")
public class Person {
  @JsonProperty("Name")
  private String name;
  @JsonProperty("NickName")
  //@JacksonXmlText
  private String nickname;
  @JsonProperty("Age")
  private int age;
  @JsonProperty("IdentityCode")
  @JacksonXmlCData
  private String identityCode;
  @JsonProperty("Birthday")
  //@JacksonXmlProperty(isAttribute = true)
  @JsonFormat(pattern = "yyyy/MM/DD")
  private LocalDate birthday;

}
다음은 코드 예제 로 기본적으로 JSON 의 API 와 매우 비슷 하 며,XmlMapper 는 사실상 Object Mapper 의 하위 클래스 이다.

    Person p1 = new Person("yitian", "  ", 25, "10000", LocalDate.of(1994, 1, 1));
    XmlMapper mapper = new XmlMapper();
    mapper.findAndRegisterModules();
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    String text = mapper.writeValueAsString(p1);
    System.out.println(text);

    Person p2 = mapper.readValue(text, Person.class);
    System.out.println(p2);
운행 결 과 는 다음 과 같다.

<Person>
 <Name>yitian</Name>
 <NickName>  </NickName>
 <Age>25</Age>
 <IdentityCode><![CDATA[10000]]></IdentityCode>
 <Birthday>1994/01/01</Birthday>
</Person>

Person(name=yitian, nickname=  , age=25, identityCode=10000, birthday=1994-01-01)

그 두 줄 의 주석 을 취소 하면 실행 결 과 는 다음 과 같 습 니 다.Jackson XML 주석 이 생 성 된 XML 에 대한 제어 효 과 를 볼 수 있 습 니 다.

<Person birthday="1994/01/01">
 <Name>yitian</Name>  
 <Age>25</Age>
 <IdentityCode><![CDATA[10000]]></IdentityCode>
</Person>

Person(name=yitian, nickname=null, age=25, identityCode=10000, birthday=1994-01-01)
스프링 부츠 통합
자동 설정
Spring Boot 는 Jackson 에 대한 지원 이 매우 완벽 합 니 다.우리 가 해당 라 이브 러 리 를 도입 하면 Spring Boot 는 상 자 를 열 때 사용 할 Bean 을 자동 으로 설정 할 수 있 습 니 다.Spring 이 자동 으로 설정 하 는 ObjectMapper(또는 XmlMapper)는 다음 과 같은 설정 을 하여 기본적으로 대부분의 상황 에 적응 할 수 있 습 니 다.
  • MapperFeature.DEPAULT 사용 하지 않 음VIEW_INCLUSION
  • DeserializationFeature.FAIL 사용 하지 않 음ON_UNKNOWN_PROPERTIES
  • SerializationFeature.WRITE 사용 하지 않 음DATES_AS_TIMESTAMPS
  • 자동 설정 을 수정 해 야 하 는 Object Mapper 속성 도 매우 간단 하 다.Spring Boot 는 환경 변 수 를 제공 하고 application.properties 파일 에서 직접 수정 하면 된다.
    
    |Jackson  |Spring    |
    |―C|―C|
    com.fasterxml.jackson.databind.DeserializationFeature|spring.jackson.deserialization.=true|false
    com.fasterxml.jackson.core.JsonGenerator.Feature|spring.jackson.generator.=true|false
    com.fasterxml.jackson.databind.MapperFeature|spring.jackson.mapper.=true|false
    com.fasterxml.jackson.core.JsonParser.Feature|spring.jackson.parser.=true|false
    com.fasterxml.jackson.databind.SerializationFeature|spring.jackson.serialization.=true|false
    com.fasterxml.jackson.annotation.JsonInclude.Include|spring.jackson.default-property-inclusion=always|non_null|non_absent|non_default|non_empty
    Spring 은 해당 하 는 HttpMessage Converters 를 동시에 설정 하기 때문에 우 리 는 사실 매우 간단하게 해 야 합 니 다.Jackson 주석 으로 매 핑 할 자바 류 를 표시 한 다음 에 컨트롤 러 를 대상 으로 돌아 가게 하면 됩 니 다!다음은 자바 류 입 니 다.
    
    @JsonRootName("person")
    public class Person {
      @JsonProperty
      private String name;
      @JsonProperty
      private int id;
      @JsonFormat(pattern = "yyyy-MM-DD")
      private LocalDate birthday;
    
      public Person(String name, int id, LocalDate birthday) {
        this.name = name;
        this.id = id;
        this.birthday = birthday;
      }
    }
    
    
    그리고 컨트롤 러 코드.전체 과정 에서 우 리 는 Jackson 라 이브 러 리 를 도입 한 후에 업무 코드 를 작성 하면 된다.Jackson 라 이브 러 리 를 어떻게 설정 하 는 지 에 대해 서 는 전혀 관여 할 필요 가 없습니다.이것 이 바로 Spring Boot 의 편리 한 점 입 니 다.
    
    @Controller
    public class MainController {
      private Person person = new Person("yitian", 10000, LocalDate.of(1994, 1, 1));
    
      @RequestMapping("/")
      public String index() {
        return "index";
      }
    
    
      @RequestMapping(value = "/json", produces = "application/json")
      @ResponseBody
      public Person json() {
        return person;
      }
    }
    
    
    localhost:8080/xml 에 들 어가 면 대응 하 는 결 과 를 볼 수 있 습 니 다.
    수 동 설정
    Spring Boot 자동 설정 은 매우 편리 하지만 만능 은 아 닙 니 다.필요 할 때 자동 으로 설 정 된 Bean 대신 Bean 을 수 동 으로 설정 해 야 합 니 다.
    
    @Configuration
    public class JacksonConfig {
      @Bean
      @Primary
      @Qualifier("xml")
      public XmlMapper xmlMapper(Jackson2ObjectMapperBuilder builder) {
        XmlMapper mapper = builder.createXmlMapper(true)
            .build();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        return mapper;
      }
    
      @Bean
      @Qualifier("json")
      public ObjectMapper jsonMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper mapper = builder.createXmlMapper(false)
            .build();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        return mapper;
      }
    }
    
    
    그리고 필요 한 곳 에 의존 주입 을 한다.ObjectMapper 와 XmlMapper 를 구분 하기 위해 서 는@Qualifier 주 해 를 사용 하여 표시 해 야 합 니 다.
    
    @Controller
    public class MainController {
      private ObjectMapper jsonMapper;
      private XmlMapper xmlMapper;
      private Person person = new Person("yitian", 10000, LocalDate.of(1994, 1, 1));
    
      public MainController(@Autowired @Qualifier("json") ObjectMapper jsonMapper, @Autowired @Qualifier("xml") XmlMapper xmlMapper) {
        this.jsonMapper = jsonMapper;
        this.xmlMapper = xmlMapper;
      }
    
    
    이상 잭 슨 라 이브 러 리 에 대한 소개 입 니 다.도움 이 되 셨 으 면 좋 겠 습 니 다.프로젝트 코드 는 제 Github 에 있 습 니 다.관심 있 는 친구 들 이 볼 수 있 습 니 다.
    자바 에서 잭 슨 의 빠 른 입문 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 잭 슨 의 빠 른 입문 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!

    좋은 웹페이지 즐겨찾기