DATAMONGO-1802 - Add Binary to byte array converter.

We now provide and register a Binary to byte[] converter to provide conversion of binary data to a byte array. MongoDB deserializes binary data using the document API to its Binary type. With this converter, we reinstantiated the previous capability to use byte arrays for binary data within domain types.

Original pull request: #505.
This commit is contained in:
Christoph Strobl
2017-10-17 10:07:47 +02:00
committed by Mark Paluch
parent 0f7460f8e8
commit 75733141c2
2 changed files with 87 additions and 13 deletions

View File

@@ -15,8 +15,6 @@
*/
package org.springframework.data.mongodb.core.convert;
import reactor.core.publisher.Flux;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.MalformedURLException;
@@ -29,9 +27,9 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.bson.Document;
import org.bson.types.Binary;
import org.bson.types.Code;
import org.bson.types.ObjectId;
import org.reactivestreams.Publisher;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalConverter;
@@ -41,6 +39,7 @@ import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mongodb.core.query.Term;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;
import org.springframework.util.StringUtils;
@@ -68,7 +67,7 @@ abstract class MongoConverters {
*/
public static Collection<Object> getConvertersToRegister() {
List<Object> converters = new ArrayList<Object>();
List<Object> converters = new ArrayList<>();
converters.add(BigDecimalToStringConverter.INSTANCE);
converters.add(StringToBigDecimalConverter.INSTANCE);
@@ -86,6 +85,7 @@ abstract class MongoConverters {
converters.add(AtomicLongToLongConverter.INSTANCE);
converters.add(LongToAtomicLongConverter.INSTANCE);
converters.add(IntegerToAtomicIntegerConverter.INSTANCE);
converters.add(BinaryToByteArrayConverter.INSTANCE);
return converters;
}
@@ -447,4 +447,22 @@ abstract class MongoConverters {
return source != null ? new AtomicInteger(source) : null;
}
}
/**
* {@link Converter} implementation capable of converting {@link Binary} to {@code byte[]}.
*
* @author Christoph Strobl
* @since 2.0.1
*/
@ReadingConverter
public static enum BinaryToByteArrayConverter implements Converter<Binary, byte[]> {
INSTANCE;
@Nullable
@Override
public byte[] convert(Binary source) {
return source.getData();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,16 +15,22 @@
*/
package org.springframework.data.mongodb.core.convert;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import lombok.Data;
import java.util.UUID;
import org.bson.types.Binary;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.test.context.ContextConfiguration;
@@ -34,37 +40,87 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* Integration tests for {@link MongoConverters}.
*
* @author Oliver Gierke
* @author Christoph Strobl
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:infrastructure.xml")
public class MongoConvertersIntegrationTests {
static final String COLLECTION = "_sample";
static final String COLLECTION = "converter-tests";
@Autowired
MongoOperations template;
@Autowired MongoOperations template;
@Before
public void setUp() {
template.dropCollection(COLLECTION);
}
@Test
@Test // DATAMONGO-422
public void writesUUIDBinaryCorrectly() {
Wrapper wrapper = new Wrapper();
wrapper.uuid = UUID.randomUUID();
template.save(wrapper);
assertThat(wrapper.id, is(notNullValue()));
assertThat(wrapper.id).isNotNull();
Wrapper result = template.findOne(Query.query(Criteria.where("id").is(wrapper.id)), Wrapper.class);
assertThat(result.uuid, is(wrapper.uuid));
assertThat(result.uuid).isEqualTo(wrapper.uuid);
}
@Test // DATAMONGO-1802
public void shouldConvertBinaryDataOnRead() {
WithBinaryDataInArray wbd = new WithBinaryDataInArray();
wbd.data = "calliope-mini".getBytes();
template.save(wbd);
assertThat(template.findOne(query(where("id").is(wbd.id)), WithBinaryDataInArray.class)).isEqualTo(wbd);
}
@Test // DATAMONGO-1802
public void shouldConvertEmptyBinaryDataOnRead() {
WithBinaryDataInArray wbd = new WithBinaryDataInArray();
wbd.data = new byte[] {};
template.save(wbd);
assertThat(template.findOne(query(where("id").is(wbd.id)), WithBinaryDataInArray.class)).isEqualTo(wbd);
}
@Test // DATAMONGO-1802
public void shouldReadBinaryType() {
WithBinaryDataType wbd = new WithBinaryDataType();
wbd.data = new Binary("calliope-mini".getBytes());
template.save(wbd);
assertThat(template.findOne(query(where("id").is(wbd.id)), WithBinaryDataType.class)).isEqualTo(wbd);
}
@Document(collection = COLLECTION)
static class Wrapper {
String id;
UUID uuid;
}
@Data
@Document(collection = COLLECTION)
static class WithBinaryDataInArray {
@Id String id;
byte[] data;
}
@Data
@Document(collection = COLLECTION)
static class WithBinaryDataType {
@Id String id;
Binary data;
}
}