* added Java ZonedDateTimeSupport Signed-off-by: Pan Li <panli@microsoft.com>
This commit is contained in:
Родитель
a8cbcd44b7
Коммит
4e69ae2168
|
@ -11,6 +11,7 @@ import lombok.NoArgsConstructor;
|
|||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class Constants {
|
||||
|
||||
public static final String DEFAULT_COLLECTION_NAME = "";
|
||||
public static final String DEFAULT_REQUEST_UNIT = "4000";
|
||||
public static final boolean DEFAULT_INDEXINGPOLICY_AUTOMATIC = true;
|
||||
|
@ -27,5 +28,7 @@ public class Constants {
|
|||
public static final String USER_AGENT_SUFFIX = "spring-data/";
|
||||
|
||||
public static final String OBJECTMAPPER_BEAN_NAME = "cosmosdbObjectMapper";
|
||||
|
||||
public static final String ISO_8601_COMPATIBLE_DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:s:SSSXXX";
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ package com.microsoft.azure.spring.data.cosmosdb.core.convert;
|
|||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.microsoft.azure.documentdb.Document;
|
||||
import com.microsoft.azure.spring.data.cosmosdb.Constants;
|
||||
import com.microsoft.azure.spring.data.cosmosdb.core.mapping.DocumentDbPersistentEntity;
|
||||
|
@ -20,15 +21,19 @@ import org.springframework.context.ApplicationContextAware;
|
|||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.convert.EntityConverter;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.microsoft.azure.spring.data.cosmosdb.Constants.ISO_8601_COMPATIBLE_DATE_PATTERN;
|
||||
|
||||
public class MappingDocumentDbConverter
|
||||
implements EntityConverter<DocumentDbPersistentEntity<?>, DocumentDbPersistentProperty, Object, Document>,
|
||||
ApplicationContextAware {
|
||||
|
@ -62,6 +67,8 @@ public class MappingDocumentDbConverter
|
|||
protected <R extends Object> R readInternal(final DocumentDbPersistentEntity<?> entity, Class<R> type,
|
||||
final Document sourceDocument) {
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
objectMapper.registerModule(provideAdvancedSerializersModule());
|
||||
|
||||
try {
|
||||
final DocumentDbPersistentProperty idProperty = entity.getIdProperty();
|
||||
final Object idValue = sourceDocument.getId();
|
||||
|
@ -75,11 +82,17 @@ public class MappingDocumentDbConverter
|
|||
|
||||
return objectMapper.readValue(jsonObject.toString(), type);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed to read the source document " + sourceDocument.toJson()
|
||||
throw new IllegalStateException("Failed to read the source document " + sourceDocument.toJson()
|
||||
+ " to target type " + type, e);
|
||||
}
|
||||
}
|
||||
|
||||
private SimpleModule provideAdvancedSerializersModule() {
|
||||
final SimpleModule simpleModule = new SimpleModule();
|
||||
simpleModule.addDeserializer(ZonedDateTime.class, new ZonedDateTimeDeserializer());
|
||||
return simpleModule;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void write(Object sourceEntity, Document document) {
|
||||
|
@ -146,6 +159,7 @@ public class MappingDocumentDbConverter
|
|||
|
||||
/**
|
||||
* Convert a property value to the value stored in CosmosDB
|
||||
*
|
||||
* @param fromPropertyValue
|
||||
* @return
|
||||
*/
|
||||
|
@ -157,6 +171,9 @@ public class MappingDocumentDbConverter
|
|||
// com.microsoft.azure.documentdb.JsonSerializable#set(String, T) cannot set values for Date and Enum correctly
|
||||
if (fromPropertyValue instanceof Date) {
|
||||
fromPropertyValue = ((Date) fromPropertyValue).getTime();
|
||||
} else if (fromPropertyValue instanceof ZonedDateTime) {
|
||||
fromPropertyValue = ((ZonedDateTime) fromPropertyValue)
|
||||
.format(DateTimeFormatter.ofPattern(ISO_8601_COMPATIBLE_DATE_PATTERN));
|
||||
} else if (fromPropertyValue instanceof Enum) {
|
||||
fromPropertyValue = fromPropertyValue.toString();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE in the project root for
|
||||
* license information.
|
||||
*/
|
||||
package com.microsoft.azure.spring.data.cosmosdb.core.convert;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
|
||||
import static com.microsoft.azure.spring.data.cosmosdb.Constants.ISO_8601_COMPATIBLE_DATE_PATTERN;
|
||||
|
||||
public class ZonedDateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {
|
||||
|
||||
@Override
|
||||
public ZonedDateTime deserialize(final JsonParser jsonParser, DeserializationContext deserializationContext)
|
||||
throws IOException {
|
||||
return parse(jsonParser);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public ZonedDateTime parse(final JsonParser jsonParser) throws IOException {
|
||||
if (jsonParser.getValueAsString() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return ZonedDateTime.parse(jsonParser.getValueAsString(),
|
||||
DateTimeFormatter.ofPattern(ISO_8601_COMPATIBLE_DATE_PATTERN));
|
||||
} catch (DateTimeParseException e) {
|
||||
throw new JsonParseException(jsonParser, jsonParser.getValueAsString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE in the project root for
|
||||
* license information.
|
||||
*/
|
||||
package com.microsoft.azure.spring.data.cosmosdb.core.convert;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class ZonedDateTimeDeserializerTest {
|
||||
|
||||
private static final String EXAMPLE_DATE_STRING = "2018-10-08T15:06:07:992Z";
|
||||
private static final String ILLEGAL_DATE_STRING = "illegal-date-string";
|
||||
private static final ZonedDateTime EXPECTED_SERIALIZED_ZONED_DATE_TIME
|
||||
= ZonedDateTime.of(2018, 10, 8, 15, 6, 7, 992000000, ZoneId.of("Z"));
|
||||
|
||||
@Test
|
||||
public void parse() throws IOException {
|
||||
final JsonParser jsonParser = Mockito.mock(JsonParser.class);
|
||||
when(jsonParser.getValueAsString()).thenReturn(EXAMPLE_DATE_STRING);
|
||||
|
||||
final ZonedDateTime zonedDateTime = new ZonedDateTimeDeserializer().parse(jsonParser);
|
||||
|
||||
assertThat(zonedDateTime.equals(EXPECTED_SERIALIZED_ZONED_DATE_TIME)).isTrue();
|
||||
}
|
||||
|
||||
@Test(expected = JsonParseException.class)
|
||||
public void testParseException() throws IOException {
|
||||
final JsonParser jsonParser = Mockito.mock(JsonParser.class);
|
||||
when(jsonParser.getValueAsString()).thenReturn(ILLEGAL_DATE_STRING);
|
||||
|
||||
new ZonedDateTimeDeserializer().parse(jsonParser);
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче