문제

저는 현재 모든 종류의 개체(구현에 대해 제어할 수 없음)를 유지해야 나중에 이러한 개체를 복구할 수 있는 프로젝트를 진행 중입니다.

개발 시 라이브러리 사용자를 제한할 수 없기 때문에 ORM을 구현할 수 없습니다.

첫 번째 대안은 Java 기본 직렬화를 사용하여 직렬화하는 것이었지만 사용자가 동일한 객체의 다른 버전(속성 변경된 유형, 이름 등)을 전달하기 시작했을 때 객체를 복구하는 데 많은 어려움을 겪었습니다.

XMLEncoder 클래스(객체를 XML로 변환)를 사용해 보았지만 기능이 부족하다는 사실을 발견했습니다(예: Enum을 지원하지 않음).

마지막으로 JAXB도 시도했지만 이로 인해 사용자는 클래스에 주석을 추가해야 했습니다.

좋은 대안이 있나요?

도움이 되었습니까?

해결책

가장 쉬운 방법은 여전히 ​​직렬화, IMO를 사용하는 것이지만 클래스의 직렬화된 형식에 대해 더 많이 생각하는 것입니다(어쨌든 실제로 수행해야 함).예를 들어:

  1. SerialUID를 명시적으로 정의합니다.
  2. 적절한 경우 고유한 직렬화된 양식을 정의하십시오.

직렬화된 형식은 클래스 API의 일부이므로 디자인 시 신중하게 생각해야 합니다.

내가 말한 거의 모든 내용이 Effective Java에서 나온 것이기 때문에 자세히 설명하지는 않겠습니다.대신에 특히 직렬화에 관한 장을 참조하겠습니다.이는 현재 겪고 있는 모든 문제에 대해 경고하고 문제에 대한 적절한 솔루션을 제공합니다.

http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683


그럼에도 불구하고 여전히 비직렬화 접근 방식을 고려하고 있다면 다음 몇 가지 사항을 참고하세요.

XML 마샬링

많은 사람들이 지적했듯이 이는 옵션이지만 이전 버전과의 호환성과 관련하여 여전히 동일한 문제에 직면하게 될 것이라고 생각합니다.그러나 XML 마샬링을 사용하면 일부 프레임워크가 초기화 중에 몇 가지 검사를 수행할 수 있으므로 이러한 문제를 즉시 발견할 수 있습니다.

YAML로/에서 변환

이것은 제가 생각해 왔던 아이디어이지만 YAML 형식(적어도 사용자 정의 toString() 형식)이 정말 마음에 들었습니다.그러나 실제로 유일한 차이점은 XML 대신 YAML로 마샬링한다는 것입니다.유일한 이점은 YAML이 XML보다 사람이 약간 더 읽기 쉽다는 것입니다.동일한 제한 사항이 적용됩니다.

다른 팁

2011 년이며 상업용 등급 REST 웹 서비스 프로젝트에서 다음 시리얼 라이저를 사용하여 고객에게 다양한 미디어 유형을 제공합니다.

  • xstream (XML이지만 JSON의 경우)
  • 잭슨 (JSON 용)
  • 크라이 (빠르고 소형 바이너리 직렬화 형식)
  • 웃다 (Jackson 1.6 이상과 함께 제공되는 이진 형식).
  • Java 객체 직렬화.

최근 다른 직렬화제를 실험했습니다.

  • 단순 렉스 견고한 것처럼 보이며 XStream의 속도는 2 배에서 실행되지만 상황에 대해 너무 많은 구성이 필요합니다.
  • Yamlbeans 몇 가지 버그가있었습니다.
  • 날짜와 관련된 사소한 버그가있었습니다.

Jackson Json, Kryo 및 Jackson Smile은 Old Old Java Object 직렬화보다 약 3 배에서 4.5 배까지 상당히 빠릅니다. Xstream은 느린쪽에 있습니다. 그러나 이것들은이 시점에서 모두 확실한 선택입니다. 우리는 다른 세 가지를 계속 모니터링합니다.

http://x-stream.github.io/ 좋다, 그것을보세요! 매우 편리합니다

어떤 구현 중에는 제어가 없습니다

해결책은입니다 이것을하지 마십시오. 유형의 구현을 제어하지 않으면 직렬화되지 않아야합니다. 이야기의 끝. Java Serialization은 다른 버전의 유형 간의 직렬화 비 호환성 관리를위한 SerialversionUid를 제공합니다. 구현을 제어하지 않으면 개발자가 클래스를 변경할 때 ID가 올바르게 변경되고 있는지 확인할 수 없습니다.

'포인트'의 간단한 예를 들어보십시오. 직교 또는 극지방 시스템으로 표현할 수 있습니다. 이러한 종류의 수정에 동적으로 대처할 수있는 시스템을 구축하는 것은 비용이 많이들 것입니다. 실제로 직렬화를 설계하는 클래스의 개발자 여야합니다.

요컨대, 그것은 기술이 아니라 잘못된 디자인입니다.

Google은 이진 프로토콜을 제시했습니다. http://code.google.com/apis/protocolbuffers/ 더 빠르고 XML에 비해 페이로드가 더 작습니다. 다른 사람들은 대체로 제안했습니다.

프로토콜 버퍼의 장점 중 하나는 C, C ++, Python 및 Java로 정보를 교환 할 수 있다는 것입니다.

JSON으로 직렬화하십시오 GSON 예를 들어.

또한 매우 빠른 JDK 직렬화 드롭 인 교체 :http://ruedigermoeller.github.io/fast-serialization/

직렬화 속도가 중요하다면 JVM 시리얼 라이저의 포괄적 인 벤치 마크가 있습니다.

개인적으로 나는 사용합니다 명성 SmallTalk (VW 및 Squeak) 및 Python과의 상호 운용성을 특징으로합니다. (면책 조항, 나는 명예 프로젝트의 주요 기여자입니다.)

혹시 비버?

betwixt 객체를 직렬화하기에 좋은 라이브러리이지만 자동 종류의 일이 아닙니다. 직렬화해야 할 객체의 수가 비교적 고정되어 있다면, 이것은 귀하에게 좋은 옵션 일 수 있지만, '고객'이 항상 새로운 수업을 던질 경우 가치보다 더 많은 노력 일 수 있습니다 ( 그러나 모든 특별한 경우에 xmlencoder보다 확실히 쉽습니다).

또 다른 접근법은 고객이 귀하에게 던지는 모든 객체에 대해 적절한 .Betwixt 파일을 제공하도록 요구하는 것입니다 (효과적으로 책임을 상쇄합니다).

길고 짧은 - 직렬화는입니다 딱딱한 - 그것에 완전히 뇌 죽은 접근 방식이 없습니다. Java Serialization은 내가 본 것만 큼 뇌 죽은 솔루션에 가깝지만, 찾은 것처럼 버전 UID 값을 잘못 사용하면이를 깨뜨릴 수 있습니다. Java Serialization은 또한 마커 '직렬화 가능한'인터페이스를 사용해야하므로 소스를 제어 할 수 없다면 그에 대한 운이 좋지 않습니다.

요구 사항이 당신이 설명하는만큼 어려운 경우, 당신은 객체 / 측면 / 무엇이든 어떤 종류의 BCE (바이트 코드 수정)에 의지해야 할 수도 있습니다. 이것은 소규모 개발 프로젝트의 영역과 최대 절전 모드, 캐스퍼 또는 orm의 영역으로 나아가고 있습니다 ....

다른 아이디어 : 캐시를 사용합니다. 캐시는 응용 프로그램에 대한 훨씬 더 나은 제어, 확장 성 및 견고성을 제공합니다. 그러나 여전히 직렬화해야하지만 캐싱 서비스 프레임 워크 내에서 관리는 훨씬 쉬워집니다. 캐시는 메모리, 디스크, 데이터베이스 또는 어레이 또는 모든 옵션으로 오버플로, 다른 옵션에 대한 실패로 유지 될 수 있습니다. Commons JCS와 Ehcache는 두 개의 Java 구현이며, 후자는 최대 32GB의 스토리지가없는 엔터프라이즈 솔루션입니다 (면책 조항 : Ehcache에서 일하지 않습니다 ;-)).

SBE는 Fast, Bytebuffer 기반 직렬화 라이브러리를위한 기존 라이브러리이며 버전 작성이 가능합니다. 그러나 길이 래퍼 클래스를 작성해야하므로 사용하기가 약간 어렵습니다.

결점에 비추어, 나는 최근 SBE와 Fix-Protocol (거래/견적 메시지를 교환하기위한 공통 금융 시장 프로토콜)에서 영감을 얻은 Java 전용 직렬화 라이브러리를 만들었습니다. 당신은 볼 수 있습니다 https://github.com/iceberglet/anymsg

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top