데이터 저장소로 MongoDB를 사용하고 있지만 직렬화/직렬화에 Jackson을 사용하고 있습니다. Mongo pojo 클래스는 Jackson과 거의 같은 시나리오를 처리하지 않습니다.jackson에서 bson long primitive json을 비 직렬화합니다.
우리는이 사용자 정의 CodecProvider를 사용하여 작업 한 - 여기 코덱 자체이다 : 우리가 Integer.MAXVALUE보다 크 긴있다 몽고에서 문서를 검색 할 때까지
class JacksonCodec<T> implements Codec<T> {
private final ObjectMapper objectMapper;
private final Codec<RawBsonDocument> rawBsonDocumentCodec;
private final Class<T> type;
public JacksonCodec(ObjectMapper objectMapper,
CodecRegistry codecRegistry,
Class<T> type) {
this.objectMapper = objectMapper;
this.rawBsonDocumentCodec = codecRegistry.get(RawBsonDocument.class);
this.type = type;
}
@Override
public T decode(BsonReader reader, DecoderContext decoderContext) {
try {
RawBsonDocument document = rawBsonDocumentCodec.decode(reader, decoderContext);
String json = document.toJson();
return objectMapper.readValue(json, type);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public void encode(BsonWriter writer, Object value, EncoderContext encoderContext) {
try {
String json = objectMapper.writeValueAsString(value);
rawBsonDocumentCodec.encode(writer, RawBsonDocument.parse(json), encoderContext);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public Class<T> getEncoderClass() {
return this.type;
}
}
이 잘 작동이. 이 경우 다음 메시지와 함께 비 직렬화가 실패합니다.
원인 : com.fasterxml.jackson.databind.JsonMappingException : START_OBJECT 토큰에서 긴 인스턴스를 deserialize 할 수 없습니다. bson 보면
는, 여기에 몽고 데이터가 우리에게 돌아 오는 방법은 다음과 같습니다
"날짜 스탬프": { "$ NumberLong으로": "1514334498165"} 그래서
... 나는 생각하고 Jackson이이 케이스를 처리 할 수있는 추가 디시리얼라이저를 등록해야합니다 (토큰 유형 ID_START_OBJECT를 확인하고, 거기에 구문 분석, 그렇지 않으면 기본 제공 디시리얼라이저에 위임).
public class BsonLongDeserializer extends JsonDeserializer<Long>{
@Override
public Class<Long> handledType() {
return Long.class;
}
@Override
public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
if (p.currentTokenId() != JsonTokenId.ID_START_OBJECT){
// have to figure out how to do this for real if we can get the deserilizer to actually get called
return ctxt.readValue(p, Long.class);
}
return null;
}
}
을하고 등록 : 나는 ObjectMapper SimpleModule있는 간단한 긴 디시리얼라이저를 등록하려고
private static ObjectMapper createMapper(){
SimpleModule module = new SimpleModule();
module.addDeserializer(Long.class, new BsonLongDeserializer());
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModule(module);
return mapper;
}
을하지만 잭슨에 의해 호출하지 도착 결코 BsonLongDeserializer은 (프리미티브는 다르게 처리 및 단락 등록 디시리얼라이저된다 아마도?).
잭슨 버전 2.9.3. MongoDB 드라이버 버전 3.6.
누군가가이 각도를 공격하는 각도에 대해 의견이 있으면 그 소리를 들려 주시면 감사하겠습니다. 도움하지 않는 것
참조 된 기사 : MongoDB "NumberLong/$numberLong" issue while converting back to Java Object