#1382 - Add ability to customize the ObjectMapper for HAL and HAL-FORMS.

Use HalConfiguration to allow applying customizations to the ObjectMapper.

Original pull request: #1383.
This commit is contained in:
Greg L. Turnquist
2020-10-27 12:59:47 -05:00
committed by Oliver Drotbohm
parent 0643624e7c
commit 89fade21c2
7 changed files with 211 additions and 7 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.hateoas.mediatype.hal;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Consumer;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkRelation;
@@ -25,6 +26,8 @@ import org.springframework.util.AntPathMatcher;
import org.springframework.util.Assert;
import org.springframework.util.PathMatcher;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* HAL specific configuration.
*
@@ -41,6 +44,7 @@ public class HalConfiguration {
*/
private final RenderSingleLinks renderSingleLinks;
private final Map<String, RenderSingleLinks> singleLinksPerPattern;
private final Consumer<ObjectMapper> objectMapperCustomizer;
/**
* Configures whether the Jackson property naming strategy is applied to link relations and within {@code _embedded}
@@ -63,15 +67,18 @@ public class HalConfiguration {
this.singleLinksPerPattern = new LinkedHashMap<>();
this.applyPropertyNamingStrategy = true;
this.enforceEmbeddedCollections = true;
this.objectMapperCustomizer = objectMapper -> {}; // Default to no action.
}
private HalConfiguration(RenderSingleLinks renderSingleLinks, Map<String, RenderSingleLinks> singleLinksPerPattern,
boolean applyPropertyNamingStrategy, boolean enforceEmbeddedCollections) {
boolean applyPropertyNamingStrategy, boolean enforceEmbeddedCollections,
Consumer<ObjectMapper> objectMapperCustomizer) {
this.renderSingleLinks = renderSingleLinks;
this.singleLinksPerPattern = singleLinksPerPattern;
this.applyPropertyNamingStrategy = applyPropertyNamingStrategy;
this.enforceEmbeddedCollections = enforceEmbeddedCollections;
this.objectMapperCustomizer = objectMapperCustomizer;
}
/**
@@ -132,7 +139,7 @@ public class HalConfiguration {
return this.renderSingleLinks == renderSingleLinks ? this
: new HalConfiguration(renderSingleLinks, this.singleLinksPerPattern, this.applyPropertyNamingStrategy,
this.enforceEmbeddedCollections);
this.enforceEmbeddedCollections, this.objectMapperCustomizer);
}
/**
@@ -145,7 +152,7 @@ public class HalConfiguration {
return this.singleLinksPerPattern == singleLinksPerPattern ? this
: new HalConfiguration(this.renderSingleLinks, singleLinksPerPattern, this.applyPropertyNamingStrategy,
this.enforceEmbeddedCollections);
this.enforceEmbeddedCollections, this.objectMapperCustomizer);
}
/**
@@ -159,7 +166,7 @@ public class HalConfiguration {
return this.applyPropertyNamingStrategy == applyPropertyNamingStrategy ? this
: new HalConfiguration(this.renderSingleLinks, this.singleLinksPerPattern, applyPropertyNamingStrategy,
this.enforceEmbeddedCollections);
this.enforceEmbeddedCollections, this.objectMapperCustomizer);
}
/**
@@ -173,7 +180,14 @@ public class HalConfiguration {
return this.enforceEmbeddedCollections == enforceEmbeddedCollections ? this
: new HalConfiguration(this.renderSingleLinks, this.singleLinksPerPattern, this.applyPropertyNamingStrategy,
enforceEmbeddedCollections);
enforceEmbeddedCollections, this.objectMapperCustomizer);
}
public HalConfiguration withObjectMapperCustomizer(Consumer<ObjectMapper> objectMapperCustomizer) {
return this.objectMapperCustomizer == objectMapperCustomizer ? this
: new HalConfiguration(this.renderSingleLinks, this.singleLinksPerPattern, this.applyPropertyNamingStrategy,
this.enforceEmbeddedCollections, objectMapperCustomizer);
}
public RenderSingleLinks getRenderSingleLinks() {
@@ -188,6 +202,10 @@ public class HalConfiguration {
return this.enforceEmbeddedCollections;
}
public Consumer<ObjectMapper> getObjectMapperCustomizer() {
return this.objectMapperCustomizer;
}
/**
* Configuration option how to render single links of a given {@link LinkRelation}.
*

View File

@@ -79,11 +79,14 @@ public class HalMediaTypeConfiguration implements HypermediaMappingInformation {
@Override
public ObjectMapper configureObjectMapper(ObjectMapper mapper) {
HalConfiguration halConfiguration = this.halConfiguration.getIfAvailable(HalConfiguration::new);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.registerModule(new Jackson2HalModule());
mapper.setHandlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(relProvider,
curieProvider.getIfAvailable(() -> CurieProvider.NONE), resolver,
halConfiguration.getIfAvailable(HalConfiguration::new), beanFactory));
curieProvider.getIfAvailable(() -> CurieProvider.NONE), resolver, halConfiguration, beanFactory));
halConfiguration.getObjectMapperCustomizer().accept(mapper);
return mapper;
}

View File

@@ -82,6 +82,8 @@ class HalFormsMediaTypeConfiguration implements HypermediaMappingInformation {
mapper.setHandlerInstantiator(new Jackson2HalFormsModule.HalFormsHandlerInstantiator(relProvider,
curieProvider.getIfAvailable(() -> CurieProvider.NONE), resolver, configuration, beanFactory));
configuration.getHalConfiguration().getObjectMapperCustomizer().accept(mapper);
return mapper;
}