如何配置Spring Data Rest以返回Json-LD或Siren媒体类型而不是HAL

时间:2018-08-27 02:39:40

标签: spring spring-data-jpa json-ld spring-hateoas hydra-core

我一直在努力寻找任何示例来说明如何可以覆盖默认的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);
  }

0 个答案:

没有答案