[Java, XML, Jackson] Binary JSON with bson4jackson  

Binary JSON with bson4jackson

Re­cently, JSON has be­come an ex­cel­lent al­tern­at­ive to XML. But most JSON pars­ers writ­ten in Java are still rather slow. On my search for faster lib­rar­ies I found two things: BSON and Jack­son.

BSON is bin­ary en­coded JSON. The format has been de­signed with fast ma­chine read­ab­il­ity in mind. BSON has gained prom­in­ence as the main data ex­change format for the doc­u­ment-ori­ented data­base man­age­ment sys­tem Mon­goDB. Ac­cord­ing to the JVM seri­al­izers bench­mark Jack­son is one of the fast­est JSON pro­cessors avail­able. Apart from that, Jack­son al­lows writ­ing cus­tom ex­ten­sions. This fea­ture can be used to add fur­ther data ex­change formats.

bson4jackson

This is the mo­ment where bson4­jack­son steps in. The lib­rary ex­tends Jack­son by the cap­ab­il­ity of read­ing and writ­ing BSON doc­u­ments. Since bson4­jack­son is fully in­teg­rated, you can use the very nice API of Jack­son to seri­al­ize simple PO­JOs. Think of the fol­low­ing class:

public class Person {
  private String _name;

  public void setName(String name) {
    _name = name;
  }

  public String getName() {
    return _name;
  }
}

You may use the ObjectMapper to quickly seri­al­ize ob­jects:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.undercouch.bson4jackson.BsonFactory;

public class ObjectMapperSample {
  public static void main(String[] args) throws Exception {
    //create dummy POJO
    Person bob = new Person();
    bob.setName("Bob");

    //serialize data
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectMapper mapper = new ObjectMapper(new BsonFactory());
    mapper.writeValue(baos, bob);

    //deserialize data
    ByteArrayInputStream bais = new ByteArrayInputStream(
      baos.toByteArray());
    Person clone_of_bob = mapper.readValue(bais, Person.class);

    assert bob.getName().equals(clone_of_bob.getName());
  }
}

Or you may use Jack­son’s stream­ing API and seri­al­ize the ob­ject manu­ally:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import de.undercouch.bson4jackson.BsonFactory;

public class ManualSample {
  public static void main(String[] args) throws Exception {
    //create dummy POJO
    Person bob = new Person();
    bob.setName("Bob");

    //create factory
    BsonFactory factory = new BsonFactory();

    //serialize data
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    JsonGenerator gen = factory.createJsonGenerator(baos);
    gen.writeStartObject();
    gen.writeFieldName("name");
    gen.writeString(bob.getName());
    gen.close();

    //deserialize data
    ByteArrayInputStream bais = new ByteArrayInputStream(
      baos.toByteArray());
    JsonParser parser = factory.createJsonParser(bais);
    Person clone_of_bob = new Person();
    parser.nextToken();
    while (parser.nextToken() != JsonToken.END_OBJECT) {
      String fieldname = parser.getCurrentName();
      parser.nextToken();
      if ("name".equals(fieldname)) {
        clone_of_bob.setName(parser.getText());
      }
    }

    assert bob.getName().equals(clone_of_bob.getName());
  }
}

Optimized streaming

One dis­ad­vant­age of BSON is the fact that each doc­u­ment be­gins with a num­ber de­not­ing the doc­u­ment’s length. When cre­at­ing an ob­ject this length has to be known in ad­vance and bson4­jack­son is forced to buf­fer the whole doc­u­ment be­fore it can be writ­ten to the OutputStream. bson4­jack­son’s parser ig­nores this length field and so you may also leave it empty. There­fore, you have to cre­ate the BsonFactory as fol­lows:

BsonFactory fac = new BsonFactory();
fac.enable(BsonGenerator.Feature.ENABLE_STREAMING);

This trick can in­crease the seri­al­iz­a­tion per­form­ance for large doc­u­ments and re­duce the memory foot­print a lot. The of­fi­cial Mon­goDB Java driver also ig­nores the length field. So, you may also use this op­tim­iz­a­tion if your bson4­jack­son-cre­ated doc­u­ments shall be read by the Mon­goDB driver.

Performance

Ver­sion 1.1.0 of bson4­jack­son in­tro­duced sup­port for Jack­son 1.7 as well as a lot of per­form­ance im­prove­ments. At the mo­ment, bson4­jack­son is much faster than the of­fi­cial Mon­goDB driver for Java (as of Janu­ary 2011). For seri­al­iz­a­tion, this is only true us­ing the stream­ing API, since Jack­son’s ObjectMapper adds a little bit of over­head (ac­tu­ally the Mon­goDB driver also uses some kind of a stream­ing API). Deseri­al­iz­a­tion is al­ways faster. The latest bench­mark res­ults can be re­viewed on the fol­low­ing web­site:

https://github.com/eishay/jvm-serializers/wiki

Compatibility with MongoDB

In ver­sion 1.2.0 bson4­jack­son’s com­pat­ib­il­ity with Mon­goDB has been im­proved a lot. Thanks to the con­tri­bu­tion by James Roper the BsonParser class now sup­ports the new HONOR_DOCUMENT_LENGTH fea­ture which makes the parser honor the first 4 bytes of a doc­u­ment which usu­ally con­tain the doc­u­ment’s size. Of course, this only works if BsonGenerator.Feature.ENABLE_STREAMING has not been en­abled dur­ing doc­u­ment gen­er­a­tion.

This fea­ture can be use­ful for read­ing con­sec­ut­ive doc­u­ments from an in­put stream pro­duced by Mon­goDB. You can en­able it as fol­lows:

BsonFactory fac = new BsonFactory();
fac.enable(BsonParser.Feature.HONOR_DOCUMENT_LENGTH);
BsonParser parser = (BsonParser)fac.createJsonParser(...);

Compatibility with Jackson

bson4­jack­son 2.x is com­pat­ible to Jack­son 2.x and higher. Due to some com­pat­ib­il­ity is­sues both lib­rar­ies’ ma­jor and minor ver­sion num­bers have to match. That means you have to use at least bson4­jack­son 2.1 if you use Jack­son 2.1, bson4­jack­son 2.2 if you use Jack­son 2.2, etc. I will try to keep bson4­jack­son up to date. If there is a com­pat­ib­il­ity is­sue I will up­date bson4­jackon, usu­ally within a couple of days after the new Jack­son ver­sion has been re­leased.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

Here’s the com­pat­ib­il­ity mat­rix for the cur­rent lib­rary ver­sions:

  Jack­son 2.7.x Jack­son 2.6.x Jack­son 2.5.x
bson4­jack­son 2.7.x Yes Yes Yes
bson4­jack­son 2.6.x No Yes Yes
bson4­jack­son 2.5.x No No Yes

If you’re look­ing for a ver­sion com­pat­ible to Jack­son 1.x, please use bson4­jack­son 1.3. It’s the last ver­sion for the 1.x branch. bson4­jack­son 1.3 is com­pat­ible to Jack­son 1.7 up to 1.9.

Download

Pre-compiled binaries

Pre-com­piled bin­ary files of bson4­jack­son can be down­loaded from Maven Cent­ral. Ad­di­tion­ally, you will need a copy of Jack­son to start right away.

Maven/​Gradle/​buildr/​sbt

Al­tern­at­ively, you may also use Maven to down­load bson4­jack­son:

<dependencies>
  <dependency>
    <groupId>de.undercouch</groupId>
    <artifactId>bson4jackson</artifactId>
    <version>2.9.2</version>
  </dependency>
</dependencies>

For Gradle you may use the fol­low­ing snip­pet:

compile 'de.undercouch:bson4jackson:2.9.2'

For buildr use the fol­low­ing snip­pet:

compile.with 'de.undercouch:bson4jackson:jar:2.9.2'

If you’re us­ing sbt, you may add the fol­low­ing line to your pro­ject:

val bson4jackson = "de.undercouch" % "bson4jackson" % "2.9.2"

License

bson4­jack­son is li­censed un­der the Apache Li­cense, Ver­sion 2.0.

Un­less re­quired by ap­plic­able law or agreed to in writ­ing, soft­ware dis­trib­uted un­der the Li­cense is dis­trib­uted on an “AS IS” BASIS, WITHOUT WAR­RANTIES OR CON­DI­TIONS OF ANY KIND, either ex­press or im­plied. See the Li­cense for the spe­cific lan­guage gov­ern­ing per­mis­sions and lim­it­a­tions un­der the Li­cense.

 

[출처] https://michelkraemer.com/binary-json-with-bson4jackson/

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
404 자바 인코딩 관련 문제 종합 정리 file 졸리운_곰 2021.01.29 40
403 JAVA) 예외처리(throw , throws) file 졸리운_곰 2021.01.24 21
402 [Java 디자인패턴] [JAVA 디자인 패턴] static을 응용한 싱글톤 패턴(Singleton Pattern) 구현 졸리운_곰 2021.01.22 20
401 예외처리 (throwable, exception, error, throws) file 졸리운_곰 2021.01.21 39
400 Eclipse -`항상 실행 백그라운드에서 실행 '창을 다시 표시하는 방법 file 졸리운_곰 2021.01.14 438
399 Prometheus + Grafana로 Java 애플리케이션 모니터링하기 file 졸리운_곰 2020.12.17 79
398 [스프링 배치] java Spring Batch 졸리운_곰 2020.12.16 76
397 [java] [MyBatis] #{} 와 ${} 개념과 차이점 졸리운_곰 2020.12.11 47
396 [java, mybatis] MyBatis에서 샾(#{})과 달러(${})의 차이는 무엇일까? 졸리운_곰 2020.12.11 66
395 [Java] 자바 extends, implements 차이 file 졸리운_곰 2020.12.10 48
394 [JAVA] String to int, int to String 형변환 컴퓨터/코딩 졸리운_곰 2020.12.10 35
393 [Java] 현재날짜 구하기 졸리운_곰 2020.12.10 15
392 [Java] [Java] Jackson으로 Json <-> Object 변환(Transformation)하기 졸리운_곰 2020.12.09 18
391 [java] jackson custom serializer, deserializer 만들기 file 졸리운_곰 2020.12.09 60
390 [Java] Deserialize MongoDB date fields to Java POJO Using Jackson 졸리운_곰 2020.12.09 132
389 [Java] Jackson ObjectMapper upper/lower case issues 졸리운_곰 2020.12.09 473
388 Java의 날짜와 시간 API file 졸리운_곰 2020.12.03 41
387 Java로 현재 날짜 / 시간을 얻는 방법 file 졸리운_곰 2020.11.30 451
386 [java, jackson] [jackson] json serialize 만 ignore 하고 싶다면? 졸리운_곰 2020.11.07 16
385 Java MongoDB : Query document 졸리운_곰 2020.11.07 30
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED