#833 - Introduce SpringFactories-based SPI for custom media types.
We now expose a MediaTypeConfigurationProvider SPI interface that media type implementations can register an implementation class for in META-INF/spring.factories. The implementation class then has to provide a root Spring configuration class to be included into the bootstrap and expose whether it's supposed to be included for a given set of media types. Configuration classes are supposed to implement HypermediaMappingInformation to expose either a Jackson module or code to configure the Jackson ObjectMapper to be used in the mapping infrastructure of the supported web stacks (WebMVC and WebFlux).
This commit is contained in:
@@ -20,7 +20,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface for components that convert a domain type into a {@link ResourceSupport}.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@@ -28,21 +28,21 @@ public interface ResourceAssembler<T, D extends ResourceSupport> {
|
||||
|
||||
/**
|
||||
* Converts the given entity into a {@code D}, which extends {@link ResourceSupport}.
|
||||
*
|
||||
*
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
D toResource(T entity);
|
||||
|
||||
/**
|
||||
* Converts an {@link Iterable} or {@code T}s into an {@link Iterable} of {@link ResourceSupport} and wraps
|
||||
* them in a {@link Resources} instance.
|
||||
*
|
||||
* Converts an {@link Iterable} or {@code T}s into an {@link Iterable} of {@link ResourceSupport} and wraps them in a
|
||||
* {@link Resources} instance.
|
||||
*
|
||||
* @param entities must not be {@literal null}.
|
||||
* @return {@link Resources} containing {@code D}.
|
||||
*/
|
||||
default Resources<D> toResources(Iterable<? extends T> entities) {
|
||||
|
||||
|
||||
List<D> resources = new ArrayList<>();
|
||||
for (T entity : entities) {
|
||||
resources.add(toResource(entity));
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.collectionjson;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.hateoas.config.MediaTypeConfigurationProvider;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class CollectionJsonConfigurationProvider implements MediaTypeConfigurationProvider {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#getConfiguration()
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends HypermediaMappingInformation> getConfiguration() {
|
||||
return CollectionJsonMediaTypeConfiguration.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#supportsAny(java.util.Collection)
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsAny(Collection<MediaType> mediaTypes) {
|
||||
return mediaTypes.contains(MediaTypes.COLLECTION_JSON);
|
||||
}
|
||||
}
|
||||
@@ -21,43 +21,40 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.hateoas.LinkDiscoverer;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.hateoas.config.Hypermedia;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.Module;
|
||||
|
||||
/**
|
||||
* Configuration setup for Collection/JSON.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Configuration
|
||||
public class CollectionJsonConfigurer {
|
||||
|
||||
@Bean
|
||||
Hypermedia collectionJsonBean() {
|
||||
|
||||
return new Hypermedia() {
|
||||
@Override
|
||||
public List<MediaType> getMediaTypes() {
|
||||
return HypermediaType.COLLECTION_JSON.getMediaTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapper createObjectMapper(ObjectMapper mapper) {
|
||||
|
||||
ObjectMapper mapper1 = mapper.copy();
|
||||
|
||||
mapper1.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
mapper1.registerModule(new Jackson2CollectionJsonModule());
|
||||
|
||||
return mapper1;
|
||||
}
|
||||
};
|
||||
}
|
||||
class CollectionJsonMediaTypeConfiguration implements HypermediaMappingInformation {
|
||||
|
||||
@Bean
|
||||
LinkDiscoverer linkDiscoverer() {
|
||||
return new CollectionJsonLinkDiscoverer();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.HypermediaMappingInformation#getMediaTypes()
|
||||
*/
|
||||
@Override
|
||||
public List<MediaType> getMediaTypes() {
|
||||
return HypermediaType.COLLECTION_JSON.getMediaTypes();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.HypermediaMappingInformation#getJacksonModule()
|
||||
*/
|
||||
@Override
|
||||
public Module getJacksonModule() {
|
||||
return new Jackson2CollectionJsonModule();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Copyright 2015-2019 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.
|
||||
@@ -63,8 +63,9 @@ import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
* in Collection+JSON compatible JSON.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public class Jackson2CollectionJsonModule extends SimpleModule {
|
||||
class Jackson2CollectionJsonModule extends SimpleModule {
|
||||
|
||||
private static final long serialVersionUID = -6540574644565592709L;
|
||||
|
||||
|
||||
@@ -22,20 +22,15 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.collectionjson.CollectionJsonConfigurer;
|
||||
import org.springframework.hateoas.hal.HalConfigurer;
|
||||
import org.springframework.hateoas.hal.forms.HalFormsConfigurer;
|
||||
import org.springframework.hateoas.uber.UberConfigurer;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* Activates hypermedia support in the {@link ApplicationContext}. Will register infrastructure beans to support all
|
||||
* appropriate web stacks based on selected {@link Hypermedia}-type as well as the classpath.
|
||||
* appropriate web stacks based on selected {@link HypermediaMappingInformation}-type as well as the classpath.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
@@ -44,7 +39,7 @@ import org.springframework.http.MediaType;
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
@EnableEntityLinks
|
||||
@Import({ HypermediaSupportBeanDefinitionRegistrar.class, HateoasConfiguration.class, WebStackImportSelector.class })
|
||||
@Import({ HypermediaConfigurationImportSelector.class, HateoasConfiguration.class, WebStackImportSelector.class })
|
||||
public @interface EnableHypermediaSupport {
|
||||
|
||||
/**
|
||||
@@ -60,7 +55,7 @@ public @interface EnableHypermediaSupport {
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
enum HypermediaType implements Hypermedia {
|
||||
enum HypermediaType {
|
||||
|
||||
/**
|
||||
* HAL - Hypermedia Application Language.
|
||||
@@ -68,47 +63,37 @@ public @interface EnableHypermediaSupport {
|
||||
* @see http://stateless.co/hal_specification.html
|
||||
* @see http://tools.ietf.org/html/draft-kelly-json-hal-05
|
||||
*/
|
||||
HAL(HalConfigurer.class, MediaTypes.HAL_JSON, MediaTypes.HAL_JSON_UTF8),
|
||||
HAL(MediaTypes.HAL_JSON, MediaTypes.HAL_JSON_UTF8),
|
||||
|
||||
/**
|
||||
* HAL-FORMS - Independent, backward-compatible extension of the HAL designed to add runtime FORM support
|
||||
*
|
||||
* @see https://rwcbook.github.io/hal-forms/
|
||||
*/
|
||||
HAL_FORMS(HalFormsConfigurer.class, MediaTypes.HAL_FORMS_JSON),
|
||||
HAL_FORMS(MediaTypes.HAL_FORMS_JSON),
|
||||
|
||||
/**
|
||||
* Collection+JSON
|
||||
*
|
||||
* @see http://amundsen.com/media-types/collection/format/
|
||||
*/
|
||||
COLLECTION_JSON(CollectionJsonConfigurer.class, MediaTypes.COLLECTION_JSON),
|
||||
COLLECTION_JSON(MediaTypes.COLLECTION_JSON),
|
||||
|
||||
/**
|
||||
* UBER Hypermedia
|
||||
*
|
||||
* @see http://uberhypermedia.org/
|
||||
*/
|
||||
UBER(UberConfigurer.class, MediaTypes.UBER_JSON);
|
||||
UBER(MediaTypes.UBER_JSON);
|
||||
|
||||
private final Class<?> configurer;
|
||||
private final List<MediaType> mediaTypes;
|
||||
|
||||
HypermediaType(Class<?> configurer, MediaType... mediaTypes) {
|
||||
|
||||
this.configurer = configurer;
|
||||
HypermediaType(MediaType... mediaTypes) {
|
||||
this.mediaTypes = Arrays.asList(mediaTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MediaType> getMediaTypes() {
|
||||
return this.mediaTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Class<?>> configurer() {
|
||||
return Optional.ofNullable(this.configurer);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.hateoas.config;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
@@ -54,17 +55,12 @@ class EntityLinksConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
ControllerEntityLinksFactoryBean controllerEntityLinks(WebMvcLinkBuilderFactory controllerLinkBuilderFactory) {
|
||||
ControllerEntityLinksFactoryBean controllerEntityLinks(ObjectProvider<WebMvcLinkBuilderFactory> linkBuilderFactory) {
|
||||
|
||||
ControllerEntityLinksFactoryBean factory = new ControllerEntityLinksFactoryBean();
|
||||
factory.setAnnotation(Controller.class);
|
||||
factory.setLinkBuilderFactory(controllerLinkBuilderFactory);
|
||||
factory.setLinkBuilderFactory(linkBuilderFactory.getIfAvailable(WebMvcLinkBuilderFactory::new));
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebMvcLinkBuilderFactory webMvcLinkBuilderFactoryBean() {
|
||||
return new WebMvcLinkBuilderFactory();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Interface for registering custom hypermedia handlers.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
public interface Hypermedia {
|
||||
|
||||
/**
|
||||
* {@link MediaType}s this hypermedia can handle.
|
||||
*/
|
||||
List<MediaType> getMediaTypes();
|
||||
|
||||
/**
|
||||
* Convert list of {@link MediaType}s into an array of {@link MimeType}s to support various Spring constructors.
|
||||
*/
|
||||
default MimeType[] getMimeTypes() {
|
||||
return getMediaTypes().toArray(new MimeType[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@link ObjectMapper} and register custom serializers and deserializers for the supported media types.
|
||||
*/
|
||||
default ObjectMapper createObjectMapper(ObjectMapper mapper) {
|
||||
return mapper.copy();
|
||||
}
|
||||
|
||||
default Optional<Class<?>> configurer() {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.context.annotation.ImportSelector;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* {@link ImportSelector} that looks up configuration classes from all {@link MediaTypeConfigurationProvider}
|
||||
* implementations listed in {@code META-INF/spring.factories}.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
class HypermediaConfigurationImportSelector implements ImportSelector {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.annotation.ImportSelector#selectImports(org.springframework.core.type.AnnotationMetadata)
|
||||
*/
|
||||
@Override
|
||||
public String[] selectImports(AnnotationMetadata metadata) {
|
||||
|
||||
Map<String, Object> attributes = metadata.getAnnotationAttributes(EnableHypermediaSupport.class.getName());
|
||||
|
||||
Collection<MediaType> types = Arrays.stream((HypermediaType[]) attributes.get("type")) //
|
||||
.flatMap(it -> it.getMediaTypes().stream()) //
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Collection<MediaTypeConfigurationProvider> configurationProviders = SpringFactoriesLoader.loadFactories(
|
||||
MediaTypeConfigurationProvider.class, HypermediaConfigurationImportSelector.class.getClassLoader());
|
||||
|
||||
// No additional filtering needed.
|
||||
if (types.isEmpty()) {
|
||||
return configurationProviders.toArray(new String[configurationProviders.size()]);
|
||||
}
|
||||
|
||||
// Filter the ones supporting the given media types
|
||||
return configurationProviders.stream() //
|
||||
.filter(it -> it.supportsAny(types)) //
|
||||
.map(MediaTypeConfigurationProvider::getConfiguration) //
|
||||
.map(Class::getName) //
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.Module;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Interface for registering custom hypermedia handlers.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public interface HypermediaMappingInformation {
|
||||
|
||||
/**
|
||||
* All {@link MediaType}s this hypermedia can handle.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<MediaType> getMediaTypes();
|
||||
|
||||
/**
|
||||
* Configure an {@link ObjectMapper} and register custom serializers and deserializers for the supported media types.
|
||||
* If all you want to do is register a Jackson {@link Module}, prefer implementing {@link #getJacksonModule()}.
|
||||
*
|
||||
* @return
|
||||
* @see #getJacksonModule()
|
||||
*/
|
||||
default ObjectMapper configureObjectMapper(ObjectMapper mapper) {
|
||||
|
||||
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
|
||||
Optional.ofNullable(getJacksonModule()).ifPresent(mapper::registerModule);
|
||||
|
||||
return mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally return the Jackson {@link Module} to be used to customize the serialization of representation models.
|
||||
* Override this if there's nothing but the module to be done to setup the {@link ObjectMapper}. For more advanced
|
||||
* needs, see {@link #configureObjectMapper(ObjectMapper)}.
|
||||
*
|
||||
* @return
|
||||
* @see #configureObjectMapper(ObjectMapper)
|
||||
*/
|
||||
default Module getJacksonModule() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config;
|
||||
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionReaderUtils.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.hateoas.EntityLinks;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link ImportBeanDefinitionRegistrar} implementation to activate hypermedia support based on the configured
|
||||
* hypermedia type. Activates {@link EntityLinks} support as well (essentially as if {@link EnableEntityLinks} was
|
||||
* activated as well).
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
class HypermediaSupportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
private static final boolean JSONPATH_PRESENT = ClassUtils.isPresent("com.jayway.jsonpath.JsonPath", null);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||
*/
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
|
||||
|
||||
Map<String, Object> attributes = metadata.getAnnotationAttributes(EnableHypermediaSupport.class.getName());
|
||||
Collection<HypermediaType> types = Arrays.asList((HypermediaType[]) attributes.get("type"));
|
||||
|
||||
/*
|
||||
* Register all the {@link HypermediaType}s as individual beans, so they can be gathered as needed into a
|
||||
* collection using the application context.
|
||||
*/
|
||||
for (HypermediaType type : types) {
|
||||
|
||||
type.configurer().ifPresent(clazz -> {
|
||||
|
||||
Assert.isTrue(clazz.isAnnotationPresent(Configuration.class),
|
||||
clazz + " must have Spring's @Configuration annotation!");
|
||||
|
||||
BeanDefinitionBuilder hypermediaTypeBeanDefinition = genericBeanDefinition(clazz);
|
||||
registerSourcedBeanDefinition(hypermediaTypeBeanDefinition, metadata, registry);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static String registerSourcedBeanDefinition(BeanDefinitionBuilder builder, AnnotationMetadata metadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
|
||||
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
|
||||
String generateBeanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, registry);
|
||||
return registerSourcedBeanDefinition(builder, metadata, registry, generateBeanName);
|
||||
}
|
||||
|
||||
private static String registerSourcedBeanDefinition(BeanDefinitionBuilder builder, AnnotationMetadata metadata,
|
||||
BeanDefinitionRegistry registry, String name) {
|
||||
|
||||
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
|
||||
beanDefinition.setSource(metadata);
|
||||
|
||||
BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, name);
|
||||
registerBeanDefinition(holder, registry);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* SPI to register a media type configuration provider.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
* @see HypermediaMappingInformation
|
||||
*/
|
||||
public interface MediaTypeConfigurationProvider {
|
||||
|
||||
/**
|
||||
* Returns the primary Spring configuration class to be bootstrapped for the given media type.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Class<? extends HypermediaMappingInformation> getConfiguration();
|
||||
|
||||
/**
|
||||
* Returns whether the provider supports any of the given {@link MediaType}s. Used to select the providers to be
|
||||
* included into a configuration setup in case the media types to be enabled are explicitly defined.
|
||||
*
|
||||
* @param mediaTypes will never be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
boolean supportsAny(Collection<MediaType> mediaTypes);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018-2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config.mvc;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* {@link BeanPostProcessor} to register hypermedia support with {@link RestTemplate} instances found in the
|
||||
* application context.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class HypermediaRestTemplateBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private final HypermediaWebMvcConfigurer configurer;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (bean instanceof RestTemplate) {
|
||||
this.configurer.extendMessageConverters(((RestTemplate) bean).getMessageConverters());
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018-2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config.mvc;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.hateoas.config.Hypermedia;
|
||||
import org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class HypermediaWebMvcConfigurer implements WebMvcConfigurer {
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private final Collection<Hypermedia> hypermediaTypes;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurer#extendMessageConverters(java.util.List)
|
||||
*/
|
||||
@Override
|
||||
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
|
||||
this.hypermediaTypes.forEach(hypermedia -> {
|
||||
|
||||
converters.add(0, new TypeConstrainedMappingJackson2HttpMessageConverter(
|
||||
ResourceSupport.class, hypermedia.getMediaTypes(), hypermedia.createObjectMapper(this.mapper)));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -15,16 +15,25 @@
|
||||
*/
|
||||
package org.springframework.hateoas.config.mvc;
|
||||
|
||||
import java.util.Collection;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.hateoas.config.Hypermedia;
|
||||
import org.springframework.hateoas.core.DelegatingRelProvider;
|
||||
import org.springframework.hateoas.hal.CurieProvider;
|
||||
import org.springframework.hateoas.hal.HalConfiguration;
|
||||
import org.springframework.hateoas.hal.forms.HalFormsConfiguration;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter;
|
||||
import org.springframework.hateoas.mvc.UriComponentsContributor;
|
||||
import org.springframework.hateoas.mvc.WebMvcLinkBuilderFactory;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@@ -34,13 +43,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@Configuration
|
||||
public class WebMvcHateoasConfiguration {
|
||||
class WebMvcHateoasConfiguration {
|
||||
|
||||
@Bean
|
||||
HypermediaWebMvcConfigurer hypermediaWebMvcConfigurer(ObjectProvider<ObjectMapper> mapper,
|
||||
// DelegatingRelProvider relProvider, ObjectProvider<CurieProvider> curieProvider,
|
||||
// ObjectProvider<HalConfiguration> halConfiguration, ObjectProvider<HalFormsConfiguration> halFormsConfiguration,
|
||||
Collection<Hypermedia> hypermediaTypes) {
|
||||
Collection<HypermediaMappingInformation> hypermediaTypes) {
|
||||
|
||||
return new HypermediaWebMvcConfigurer(mapper.getIfAvailable(ObjectMapper::new), hypermediaTypes);
|
||||
}
|
||||
@@ -49,4 +56,67 @@ public class WebMvcHateoasConfiguration {
|
||||
HypermediaRestTemplateBeanPostProcessor restTemplateBeanPostProcessor(HypermediaWebMvcConfigurer configurer) {
|
||||
return new HypermediaRestTemplateBeanPostProcessor(configurer);
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebMvcLinkBuilderFactory webMvcLinkBuilderFactory(ObjectProvider<UriComponentsContributor> contributors) {
|
||||
|
||||
WebMvcLinkBuilderFactory factory = new WebMvcLinkBuilderFactory();
|
||||
factory.setUriComponentsContributors(contributors.stream().collect(Collectors.toList()));
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class HypermediaWebMvcConfigurer implements WebMvcConfigurer {
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private final Collection<HypermediaMappingInformation> hypermediaTypes;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurer#extendMessageConverters(java.util.List)
|
||||
*/
|
||||
@Override
|
||||
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
|
||||
this.hypermediaTypes.forEach(hypermedia -> {
|
||||
|
||||
converters.add(0, new TypeConstrainedMappingJackson2HttpMessageConverter(ResourceSupport.class,
|
||||
hypermedia.getMediaTypes(), hypermedia.configureObjectMapper(mapper.copy())));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BeanPostProcessor} to register hypermedia support with {@link RestTemplate} instances found in the
|
||||
* application context.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class HypermediaRestTemplateBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private final HypermediaWebMvcConfigurer configurer;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (!RestTemplate.class.isInstance(bean)) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
configurer.extendMessageConverters(((RestTemplate) bean).getMessageConverters());
|
||||
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config.reactive;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* {@link BeanPostProcessor} to register the proper handlers in {@link WebClient} instances found in the
|
||||
* application context.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @since 1.0
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class HypermediaWebClientBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private final WebClientConfigurer configurer;
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (bean instanceof WebClient) {
|
||||
return this.configurer.registerHypermediaTypes((WebClient) bean);
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config.reactive;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.codec.CharSequenceEncoder;
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.hateoas.config.Hypermedia;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.web.reactive.config.WebFluxConfigurer;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* {@link WebFluxConfigurer} to register hypermedia-aware {@link org.springframework.core.codec.Encoder}s and
|
||||
* {@link org.springframework.core.codec.Decoder}s that will render hypermedia for WebFlux controllers.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @since 1.0
|
||||
*/
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class HypermediaWebFluxConfigurer implements WebFluxConfigurer {
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private final Collection<Hypermedia> hypermediaTypes;
|
||||
|
||||
/**
|
||||
* Configure custom HTTP message readers and writers or override built-in ones.
|
||||
* <p>
|
||||
* The configured readers and writers will be used for both annotated controllers and functional endpoints.
|
||||
*
|
||||
* @param configurer the configurer to use
|
||||
*/
|
||||
@Override
|
||||
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
|
||||
|
||||
CodecConfigurer.CustomCodecs customCodecs = configurer.customCodecs();
|
||||
|
||||
this.hypermediaTypes.forEach(hypermedia -> {
|
||||
|
||||
ObjectMapper objectMapper = hypermedia.createObjectMapper(this.mapper);
|
||||
customCodecs.encoder(new Jackson2JsonEncoder(objectMapper, hypermedia.getMimeTypes()));
|
||||
customCodecs.decoder(new Jackson2JsonDecoder(objectMapper, hypermedia.getMimeTypes()));
|
||||
});
|
||||
|
||||
customCodecs.encoder(CharSequenceEncoder.allMimeTypes());
|
||||
customCodecs.decoder(StringDecoder.allMimeTypes());
|
||||
|
||||
configurer.registerDefaults(false);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,3 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config.reactive;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -27,7 +12,7 @@ import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.hateoas.config.Hypermedia;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.util.MimeType;
|
||||
@@ -47,11 +32,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
public class WebClientConfigurer {
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private final Collection<Hypermedia> hypermediaTypes;
|
||||
private final Collection<HypermediaMappingInformation> hypermediaTypes;
|
||||
|
||||
/**
|
||||
* Return a set of {@link ExchangeStrategies} driven by registered {@link HypermediaType}s.
|
||||
*
|
||||
*
|
||||
* @return a collection of {@link Encoder}s and {@link Decoder} assembled into a {@link ExchangeStrategies}.
|
||||
*/
|
||||
public ExchangeStrategies hypermediaExchangeStrategies() {
|
||||
@@ -61,10 +46,11 @@ public class WebClientConfigurer {
|
||||
|
||||
this.hypermediaTypes.forEach(hypermedia -> {
|
||||
|
||||
ObjectMapper objectMapper = hypermedia.createObjectMapper(this.mapper);
|
||||
ObjectMapper objectMapper = hypermedia.configureObjectMapper(this.mapper.copy());
|
||||
MimeType[] mimeTypes = hypermedia.getMediaTypes().toArray(new MimeType[0]);
|
||||
|
||||
encoders.add(new Jackson2JsonEncoder(objectMapper, hypermedia.getMediaTypes().toArray(new MimeType[]{})));
|
||||
decoders.add(new Jackson2JsonDecoder(objectMapper, hypermedia.getMediaTypes().toArray(new MimeType[]{})));
|
||||
encoders.add(new Jackson2JsonEncoder(objectMapper, mimeTypes));
|
||||
decoders.add(new Jackson2JsonDecoder(objectMapper, mimeTypes));
|
||||
});
|
||||
|
||||
encoders.add(CharSequenceEncoder.allMimeTypes());
|
||||
@@ -86,7 +72,6 @@ public class WebClientConfigurer {
|
||||
* @return mutated webClient with hypermedia support.
|
||||
*/
|
||||
public WebClient registerHypermediaTypes(WebClient webClient) {
|
||||
|
||||
return webClient.mutate().exchangeStrategies(hypermediaExchangeStrategies()).build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,17 +15,26 @@
|
||||
*/
|
||||
package org.springframework.hateoas.config.reactive;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.hateoas.config.Hypermedia;
|
||||
import org.springframework.hateoas.core.DelegatingRelProvider;
|
||||
import org.springframework.hateoas.hal.CurieProvider;
|
||||
import org.springframework.hateoas.hal.HalConfiguration;
|
||||
import org.springframework.hateoas.hal.forms.HalFormsConfiguration;
|
||||
import org.springframework.core.codec.CharSequenceEncoder;
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.hateoas.reactive.HypermediaWebFilter;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.web.reactive.config.WebFluxConfigurer;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@@ -36,12 +45,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
* @since 1.0
|
||||
*/
|
||||
@Configuration
|
||||
public class WebFluxHateoasConfiguration {
|
||||
class WebFluxHateoasConfiguration {
|
||||
|
||||
@Bean
|
||||
WebClientConfigurer webClientConfigurer(ObjectProvider<ObjectMapper> mapper,
|
||||
Collection<Hypermedia> hypermediaTypes) {
|
||||
|
||||
Collection<HypermediaMappingInformation> hypermediaTypes) {
|
||||
return new WebClientConfigurer(mapper.getIfAvailable(ObjectMapper::new), hypermediaTypes);
|
||||
}
|
||||
|
||||
@@ -52,7 +60,7 @@ public class WebFluxHateoasConfiguration {
|
||||
|
||||
@Bean
|
||||
HypermediaWebFluxConfigurer hypermediaWebFluxConfigurer(ObjectProvider<ObjectMapper> mapper,
|
||||
Collection<Hypermedia> hypermediaTypes) {
|
||||
Collection<HypermediaMappingInformation> hypermediaTypes) {
|
||||
|
||||
return new HypermediaWebFluxConfigurer(mapper.getIfAvailable(ObjectMapper::new), hypermediaTypes);
|
||||
}
|
||||
@@ -65,4 +73,73 @@ public class WebFluxHateoasConfiguration {
|
||||
HypermediaWebFilter hypermediaWebFilter() {
|
||||
return new HypermediaWebFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BeanPostProcessor} to register the proper handlers in {@link WebClient} instances found in the application
|
||||
* context.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @since 1.0
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class HypermediaWebClientBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private final WebClientConfigurer configurer;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (bean instanceof WebClient) {
|
||||
return this.configurer.registerHypermediaTypes((WebClient) bean);
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link WebFluxConfigurer} to register hypermedia-aware {@link org.springframework.core.codec.Encoder}s and
|
||||
* {@link org.springframework.core.codec.Decoder}s that will render hypermedia for WebFlux controllers.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @since 1.0
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class HypermediaWebFluxConfigurer implements WebFluxConfigurer {
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private final Collection<HypermediaMappingInformation> hypermediaTypes;
|
||||
|
||||
/**
|
||||
* Configure custom HTTP message readers and writers or override built-in ones.
|
||||
* <p>
|
||||
* The configured readers and writers will be used for both annotated controllers and functional endpoints.
|
||||
*
|
||||
* @param configurer the configurer to use
|
||||
*/
|
||||
@Override
|
||||
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
|
||||
|
||||
CodecConfigurer.CustomCodecs customCodecs = configurer.customCodecs();
|
||||
|
||||
this.hypermediaTypes.forEach(hypermedia -> {
|
||||
|
||||
MimeType[] mimeTypes = hypermedia.getMediaTypes().toArray(new MimeType[0]);
|
||||
|
||||
ObjectMapper objectMapper = hypermedia.configureObjectMapper(this.mapper.copy());
|
||||
customCodecs.encoder(new Jackson2JsonEncoder(objectMapper, mimeTypes));
|
||||
customCodecs.decoder(new Jackson2JsonDecoder(objectMapper, mimeTypes));
|
||||
});
|
||||
|
||||
customCodecs.encoder(CharSequenceEncoder.allMimeTypes());
|
||||
customCodecs.decoder(StringDecoder.allMimeTypes());
|
||||
|
||||
configurer.registerDefaults(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.hal;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.hateoas.config.MediaTypeConfigurationProvider;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* {@link MediaTypeConfigurationProvider} for HAL.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
class HalConfigurationProvider implements MediaTypeConfigurationProvider {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.HyperMediaTypeProvider#getConfiguration()
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends HypermediaMappingInformation> getConfiguration() {
|
||||
return HalMediaTypeConfiguration.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.HyperMediaTypeProvider#supportsAny(java.util.Collection)
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsAny(Collection<MediaType> mediaTypes) {
|
||||
return mediaTypes.contains(MediaTypes.HAL_JSON);
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.hal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.hateoas.LinkDiscoverer;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.hateoas.config.Hypermedia;
|
||||
import org.springframework.hateoas.core.DelegatingRelProvider;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@Configuration
|
||||
public class HalConfigurer {
|
||||
|
||||
@Bean
|
||||
Hypermedia halBean(DelegatingRelProvider relProvider,
|
||||
ObjectProvider<CurieProvider> curieProvider,
|
||||
ObjectProvider<HalConfiguration> halConfiguration,
|
||||
MessageSourceAccessor messageSourceAccessor) {
|
||||
|
||||
return new Hypermedia() {
|
||||
@Override
|
||||
public List<MediaType> getMediaTypes() {
|
||||
return HypermediaType.HAL.getMediaTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapper createObjectMapper(ObjectMapper mapper) {
|
||||
|
||||
ObjectMapper mapper1 = mapper.copy();
|
||||
|
||||
mapper1.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
mapper1.registerModule(new Jackson2HalModule());
|
||||
mapper1.setHandlerInstantiator(
|
||||
new Jackson2HalModule.HalHandlerInstantiator(relProvider, curieProvider.getIfAvailable(), messageSourceAccessor, halConfiguration.getIfAvailable(HalConfiguration::new)));
|
||||
|
||||
return mapper1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
LinkDiscoverer linkDiscoverer() {
|
||||
return new HalLinkDiscoverer();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.hal;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.hateoas.LinkDiscoverer;
|
||||
import org.springframework.hateoas.RelProvider;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Spring configuration to set up HAL support.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class HalMediaTypeConfiguration implements HypermediaMappingInformation {
|
||||
|
||||
private final RelProvider relProvider;
|
||||
private final ObjectProvider<CurieProvider> curieProvider;
|
||||
private final ObjectProvider<HalConfiguration> halConfiguration;
|
||||
private final MessageSourceAccessor messageSourceAccessor;
|
||||
|
||||
@Bean
|
||||
LinkDiscoverer linkDiscoverer() {
|
||||
return new HalLinkDiscoverer();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.HypermediaMappingInformation#getMediaTypes()
|
||||
*/
|
||||
@Override
|
||||
public List<MediaType> getMediaTypes() {
|
||||
return HypermediaType.HAL.getMediaTypes();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.HypermediaMappingInformation#configureObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)
|
||||
*/
|
||||
@Override
|
||||
public ObjectMapper configureObjectMapper(ObjectMapper mapper) {
|
||||
|
||||
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
mapper.registerModule(new Jackson2HalModule());
|
||||
mapper.setHandlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(relProvider,
|
||||
curieProvider.getIfAvailable(), messageSourceAccessor, halConfiguration.getIfAvailable(HalConfiguration::new)));
|
||||
|
||||
return mapper;
|
||||
}
|
||||
}
|
||||
@@ -428,8 +428,8 @@ public class Jackson2HalModule extends SimpleModule {
|
||||
|
||||
HalLink halLink = HalLink.class.cast(firstElement);
|
||||
|
||||
if (list.size() == 1
|
||||
&& halConfiguration.getSingleLinkRenderModeFor(halLink.getLink().getRel()).equals(RenderSingleLinks.AS_SINGLE)) {
|
||||
if (list.size() == 1 && halConfiguration.getSingleLinkRenderModeFor(halLink.getLink().getRel())
|
||||
.equals(RenderSingleLinks.AS_SINGLE)) {
|
||||
|
||||
serializeContents(halLink, jgen, provider);
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.springframework.hateoas.hal.HalConfiguration;
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class HalFormsConfiguration {
|
||||
class HalFormsConfiguration {
|
||||
|
||||
private @Wither @Getter RenderSingleLinks renderSingleLinks = RenderSingleLinks.AS_SINGLE;
|
||||
|
||||
@@ -48,7 +48,7 @@ public class HalFormsConfiguration {
|
||||
|
||||
/**
|
||||
* Translate a {@link HalFormsConfiguration} into a {@link HalConfiguration}.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public HalConfiguration toHalConfiguration() {
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.hal.forms;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.hateoas.config.MediaTypeConfigurationProvider;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* {@link MediaTypeConfigurationProvider} for HAL Forms.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
class HalFormsConfigurationProvider implements MediaTypeConfigurationProvider {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#getConfiguration()
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends HypermediaMappingInformation> getConfiguration() {
|
||||
return HalFormsMediaTypeConfiguration.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#supportsAny(java.util.Collection)
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsAny(Collection<MediaType> mediaTypes) {
|
||||
return mediaTypes.contains(MediaTypes.HAL_FORMS_JSON);
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.hal.forms;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.hateoas.LinkDiscoverer;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.hateoas.config.Hypermedia;
|
||||
import org.springframework.hateoas.core.DelegatingRelProvider;
|
||||
import org.springframework.hateoas.hal.CurieProvider;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@Configuration
|
||||
public class HalFormsConfigurer {
|
||||
|
||||
@Bean
|
||||
Hypermedia halFormsBean(DelegatingRelProvider relProvider,
|
||||
ObjectProvider<CurieProvider> curieProvider,
|
||||
ObjectProvider<HalFormsConfiguration> halFormsConfiguration,
|
||||
MessageSourceAccessor messageSourceAccessor) {
|
||||
|
||||
return new Hypermedia() {
|
||||
@Override
|
||||
public List<MediaType> getMediaTypes() {
|
||||
return HypermediaType.HAL_FORMS.getMediaTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapper createObjectMapper(ObjectMapper mapper) {
|
||||
|
||||
ObjectMapper mapper1 = mapper.copy();
|
||||
|
||||
mapper1.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
mapper1.registerModule(new Jackson2HalFormsModule());
|
||||
mapper1.setHandlerInstantiator(new Jackson2HalFormsModule.HalFormsHandlerInstantiator(relProvider, curieProvider.getIfAvailable(), messageSourceAccessor,
|
||||
true, halFormsConfiguration.getIfAvailable(HalFormsConfiguration::new)));
|
||||
|
||||
return mapper1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean LinkDiscoverer linkDiscoverer() {
|
||||
return new HalFormsLinkDiscoverer();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.hal.forms;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.hateoas.LinkDiscoverer;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.hateoas.core.DelegatingRelProvider;
|
||||
import org.springframework.hateoas.hal.CurieProvider;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Spring configuration for HAL Forms support.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
class HalFormsMediaTypeConfiguration implements HypermediaMappingInformation {
|
||||
|
||||
private final DelegatingRelProvider relProvider;
|
||||
private final ObjectProvider<CurieProvider> curieProvider;
|
||||
private final ObjectProvider<HalFormsConfiguration> halFormsConfiguration;
|
||||
private final MessageSourceAccessor messageSourceAccessor;
|
||||
|
||||
@Bean
|
||||
LinkDiscoverer linkDiscoverer() {
|
||||
return new HalFormsLinkDiscoverer();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.HypermediaMappingInformation#getMediaTypes()
|
||||
*/
|
||||
@Override
|
||||
public List<MediaType> getMediaTypes() {
|
||||
return HypermediaType.HAL_FORMS.getMediaTypes();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.HypermediaMappingInformation#configureObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)
|
||||
*/
|
||||
@Override
|
||||
public ObjectMapper configureObjectMapper(ObjectMapper mapper) {
|
||||
|
||||
ObjectMapper mapper1 = mapper.copy();
|
||||
|
||||
mapper1.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
mapper1.registerModule(new Jackson2HalFormsModule());
|
||||
mapper1.setHandlerInstantiator(
|
||||
new Jackson2HalFormsModule.HalFormsHandlerInstantiator(relProvider, curieProvider.getIfAvailable(),
|
||||
messageSourceAccessor, true, halFormsConfiguration.getIfAvailable(HalFormsConfiguration::new)));
|
||||
|
||||
return mapper1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -71,7 +71,7 @@ import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class Jackson2HalFormsModule extends SimpleModule {
|
||||
class Jackson2HalFormsModule extends SimpleModule {
|
||||
|
||||
private static final long serialVersionUID = -4496351128468451196L;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.springframework.http.MediaType;
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public class UberAffordanceModelFactory implements AffordanceModelFactory {
|
||||
class UberAffordanceModelFactory implements AffordanceModelFactory {
|
||||
|
||||
private final @Getter MediaType mediaType = MediaTypes.UBER_JSON;
|
||||
|
||||
|
||||
@@ -21,43 +21,40 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.hateoas.LinkDiscoverer;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.hateoas.config.Hypermedia;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.Module;
|
||||
|
||||
/**
|
||||
* Spring configuration for Uber media type support.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Configuration
|
||||
public class UberConfigurer {
|
||||
|
||||
@Bean
|
||||
Hypermedia uberBean() {
|
||||
|
||||
return new Hypermedia() {
|
||||
@Override
|
||||
public List<MediaType> getMediaTypes() {
|
||||
return HypermediaType.UBER.getMediaTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapper createObjectMapper(ObjectMapper mapper) {
|
||||
|
||||
ObjectMapper mapper1 = mapper.copy();
|
||||
|
||||
mapper1.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
mapper1.registerModule(new Jackson2UberModule());
|
||||
|
||||
return mapper1;
|
||||
}
|
||||
};
|
||||
}
|
||||
class UberMediaTypeConfiguration implements HypermediaMappingInformation {
|
||||
|
||||
@Bean
|
||||
LinkDiscoverer linkDiscoverer() {
|
||||
return new UberLinkDiscoverer();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.HypermediaMappingInformation#getMediaTypes()
|
||||
*/
|
||||
@Override
|
||||
public List<MediaType> getMediaTypes() {
|
||||
return HypermediaType.UBER.getMediaTypes();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.HypermediaMappingInformation#getJacksonModule()
|
||||
*/
|
||||
@Override
|
||||
public Module getJacksonModule() {
|
||||
return new Jackson2UberModule();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.uber;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.hateoas.config.MediaTypeConfigurationProvider;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* {@link MediaTypeConfigurationProvider} for Uber.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
class UberMediaTypeConfigurationProvider implements MediaTypeConfigurationProvider {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#getConfiguration()
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends HypermediaMappingInformation> getConfiguration() {
|
||||
return UberMediaTypeConfiguration.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#supportsAny(java.util.Collection)
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsAny(Collection<MediaType> mediaTypes) {
|
||||
return mediaTypes.contains(MediaTypes.UBER_JSON);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user