我一直在努力寻找任何示例来说明如何可以覆盖默认的Spring Boot Data Rest JpaRepository行为以返回HAL响应以外的内容的示例。我发现,Siren和Json-LD都可以满足要求,但没有任何使其与Spring一起工作的示例。我正在使用Spring 5,Spring Data Rest 2.0.4.RELEASE。 请注意,我不是要为自定义的rest控制器执行此操作,而是要扩展JpaRepository提供的默认存储库。这是我的第一次发布,因此对于我可能无意中违反的任何规则深表歉意。
更新:按照仓库中的示例,我能够找到具有SirenMessageConverter的库hydra-spring,我可以执行以下操作:
@Configuration
@EnablePluginRegistries(RelProvider.class)
public class Config implements WebMvcConfigurer {
private static final boolean EVO_PRESENT =
ClassUtils.isPresent("org.atteo.evo.inflector.English", null);
@Autowired
private PluginRegistry<RelProvider, Class<?>> relProviderRegistry;
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(sirenMessageConverter());
converters.add(hydraMessageConverter());
converters.add(halConverter());
converters.add(uberConverter());
converters.add(xhtmlMessageConverter());
converters.add(jsonConverter());
}
@Bean
public RepositoryRestConfigurerAdapter repositoryRestConfigurer() {
return new RepositoryRestConfigurerAdapter() {
@Override
public void configureHttpMessageConverters(
List<HttpMessageConverter<?>> messageConverters) {
messageConverters.add(0, sirenMessageConverter());
}
};
}
@Bean
public HttpMessageConverter<?> uberConverter() {
UberJackson2HttpMessageConverter converter = new UberJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(Collections.singletonList(HypermediaTypes.UBER_JSON));
return converter;
}
private HttpMessageConverter<?> xhtmlMessageConverter() {
XhtmlResourceMessageConverter xhtmlResourceMessageConverter = new XhtmlResourceMessageConverter();
xhtmlResourceMessageConverter.setStylesheets(
Arrays.asList(
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"
));
xhtmlResourceMessageConverter.setDocumentationProvider(new JsonLdDocumentationProvider());
return xhtmlResourceMessageConverter;
}
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
final ExceptionHandlerExceptionResolver resolver = new ExceptionHandlerExceptionResolver();
resolver.setWarnLogCategory(resolver.getClass()
.getName());
exceptionResolvers.add(resolver);
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(HypermediaTypes.SIREN_JSON);
}
@Bean
public HydraMessageConverter hydraMessageConverter() {
return new HydraMessageConverter();
}
@Bean
public SirenMessageConverter sirenMessageConverter() {
SirenMessageConverter sirenMessageConverter = new SirenMessageConverter();
sirenMessageConverter.setRelProvider(new DelegatingRelProvider(relProviderRegistry));
sirenMessageConverter.setDocumentationProvider(new JsonLdDocumentationProvider());
sirenMessageConverter.setSupportedMediaTypes(Collections.singletonList(HypermediaTypes.SIREN_JSON));
return sirenMessageConverter;
}
@Bean
public ObjectMapper jacksonObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
return objectMapper;
}
@Bean
public MappingJackson2HttpMessageConverter jsonConverter() {
MappingJackson2HttpMessageConverter jacksonConverter = new
MappingJackson2HttpMessageConverter();
jacksonConverter.setSupportedMediaTypes(Arrays.asList(MediaType.valueOf("application/json")));
jacksonConverter.setObjectMapper(jacksonObjectMapper());
return jacksonConverter;
}
@Bean
public CurieProvider curieProvider() {
return new DefaultCurieProvider("ex", new UriTemplate("http://localhost:8080/webapp/hypermedia-api/rels/{rels}"));
}
@Bean
public MappingJackson2HttpMessageConverter halConverter() {
CurieProvider curieProvider = curieProvider();
RelProvider relProvider = new DelegatingRelProvider(relProviderRegistry);
ObjectMapper halObjectMapper = new ObjectMapper();
halObjectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
halObjectMapper.registerModule(new Jackson2HalModule());
halObjectMapper.setHandlerInstantiator(new
Jackson2HalModule.HalHandlerInstantiator(relProvider, curieProvider, null));
MappingJackson2HttpMessageConverter halConverter = new
MappingJackson2HttpMessageConverter();
halConverter.setSupportedMediaTypes(Arrays.asList(MediaTypes.HAL_JSON));
halConverter.setObjectMapper(halObjectMapper);
return halConverter;
}
@Bean
RelProvider defaultRelProvider() {
return EVO_PRESENT ? new EvoInflectorRelProvider() : new DefaultRelProvider();
}
@Bean
RelProvider annotationRelProvider() {
return new AnnotationRelProvider();
}
}
这是我当前的Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="`http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd`">
<modelVersion>`4.0.0`</modelVersion>
<groupId>com.knowledgebase.DataRest</groupId>
<artifactId>DataRest</artifactId>
<version>2.1.0.M2</version>
<packaging>jar</packaging>
<name>DataRest</name>
<description>Demo project for Spring Boot DataRest</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath /><!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>
<dependency>
<groupId>de.escalon.hypermedia</groupId>
<artifactId>hydra-spring</artifactId>
<version>0.4.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<url>http://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
</project>
但是,这仍然无法提供我想要的结果。我知道我在config类中引入的一些更改会有所作为,因为输出现在看起来像这样:
{
"_embedded": {
"ex:contacts": []
},
"_links": {
"self": {
"href": "http://localhost:8080/contacts{?page,size,sort}",
"templated": true
},
"profile": {
"href": "http://localhost:8080/profile/contacts"
},
"search": {
"href": "http://localhost:8080/contacts/search"
},
"curies": [
{
"href": "http://localhost:8080/webapp/hypermedia-api/rels/{rels}",
"name": "ex",
"templated": true
}
]
},
"page": {
"size": 20,
"totalElements": 0,
"totalPages": 0,
"number": 0
}
}
如您所见,Curries提供程序是唯一有效的方法。由于某些原因,尽管存在以下原因,spring boot数据rest JpaRepository不会将默认应用程序类型更改为SIREN_JSON:
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(HypermediaTypes.SIREN_JSON);
}