Use FormattingConversionService in JSON Patch binding.

We no pipe the Spring MVC ConversionService into the JSON Patch path binding. That usually is a FormattingConversionService at runtime and also supports the conversion of dates.

The ConversionServices is configured into the BindContext(Factory) we use for binding. The context then exposes the EvaluationContext set up with it.

Fixes #2233.
This commit is contained in:
Oliver Drotbohm
2023-02-21 18:40:31 +01:00
parent 2a88cc7ea6
commit fb1924286a
9 changed files with 78 additions and 17 deletions

View File

@@ -20,6 +20,7 @@ import java.util.Collection;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.rest.webmvc.json.BindContextFactory;
@@ -45,7 +46,8 @@ public class JsonPointerMappingTests {
context.getPersistentEntity(Sample.class);
PersistentEntities entities = new PersistentEntities(Arrays.asList(context));
BindContextFactory factory = new PersistentEntitiesBindContextFactory(entities);
BindContextFactory factory = new PersistentEntitiesBindContextFactory(entities,
DefaultConversionService.getSharedInstance());
ObjectMapper mapper = new ObjectMapper();
this.verifier = new JsonPointerMapping(factory.getBindContextFor(mapper));

View File

@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.*;
import lombok.Data;
import lombok.Getter;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -33,6 +34,7 @@ import org.springframework.data.rest.webmvc.json.BindContextFactory;
import org.springframework.data.rest.webmvc.json.PersistentEntitiesBindContextFactory;
import org.springframework.data.rest.webmvc.json.patch.SpelPath.UntypedSpelPath;
import org.springframework.data.rest.webmvc.json.patch.SpelPath.WritingOperations;
import org.springframework.format.support.DefaultFormattingConversionService;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -57,7 +59,8 @@ class SpelPathUnitTests {
context.getPersistentEntity(Person.class);
PersistentEntities entities = new PersistentEntities(Arrays.asList(context));
BindContextFactory factory = new PersistentEntitiesBindContextFactory(entities);
BindContextFactory factory = new PersistentEntitiesBindContextFactory(entities,
new DefaultFormattingConversionService());
this.context = factory.getBindContextFor(new ObjectMapper());
}
@@ -167,6 +170,18 @@ class SpelPathUnitTests {
assertThat(path.getExpressionString()).isEqualTo("renamed");
}
@Test // #2233
void bindsDatesProperly() {
Person person = new Person();
SpelPath.untyped("/birthday")
.bindForWrite(Person.class, context)
.setValue(person, "2000-01-01");
assertThat(person.birthday).isEqualTo(LocalDate.of(2000, 1, 1));
}
// DATAREST-1338
@Data
@@ -175,6 +190,7 @@ class SpelPathUnitTests {
@JsonIgnore String hiddenProperty;
@Getter(onMethod = @__(@JsonIgnore)) String hiddenGetter;
@JsonProperty("demaner") String renamed;
LocalDate birthday;
}
@Data

View File

@@ -17,6 +17,9 @@ package org.springframework.data.rest.webmvc.json.patch;
import java.util.Optional;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
public class TestPropertyPathContext implements BindContext {
public static final BindContext INSTANCE = new TestPropertyPathContext();
@@ -38,4 +41,13 @@ public class TestPropertyPathContext implements BindContext {
public Optional<String> getWritableProperty(String segment, Class<?> type) {
return Optional.of(segment);
}
/*
* (non-Javadoc)
* @see org.springframework.data.rest.webmvc.json.patch.BindContext#getEvaluationContext()
*/
@Override
public EvaluationContext getEvaluationContext() {
return SimpleEvaluationContext.forReadWriteDataBinding().build();
}
}