如何全局自定义Spring Data REST资源的集合资源rel和路径



基于https://spring.io/guides/gs/accessing-data-rest/在示例项目中https://github.com/jcoig/gs-accessing-data-rest)我的存储库定义如下:

@RepositoryRestResource
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
    List<Person> findByLastName(@Param("name") String name);
}

这样定义的存储库可通过http://localhost:8080/persons获得,响应为:

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons{?page,size,sort}",
      "templated" : true
    },
    "search" : {
      "href" : "http://localhost:8080/persons/search"
    }
  },
  "_embedded" : {
    "persons" : [ {
      "firstName" : "John",
      "lastName" : "Smith",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/persons/1"
        }
      }
    } ]
  },
  "page" : {
    "size" : 20,
    "totalElements" : 1,
    "totalPages" : 1,
    "number" : 0
  }
}

我不希望在URL中有persons,也不希望在返回的JSON中使用persons作为关键字。当然,我可以将我的存储库定义如下:

@RepositoryRestResource(collectionResourceRel = "key", path = "path")
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
    List<Person> findByLastName(@Param("name") String name);
}

但我的问题是如何更改默认Spring的行为,并获得自定义密钥和自定义路径提供程序(只是禁用s后缀的示例)。

如果在自定义RelProvider实例上应用@Order(value = Ordered.HIGHEST_PRECEDENCE)的解决方案不起作用,以下解决方案可能会有所帮助:

@Configuration
@Import(RepositoryRestMvcConfiguration.class)
public class RestMvcConfigurer extends RepositoryRestMvcConfiguration
{
...
@Override
public ResourceMappings resourceMappings()
{
  final Repositories repositories = repositories();
  final RepositoryRestConfiguration config = config();
  return new RepositoryResourceMappings( config, repositories, new YourCustomRelProvider());
}
}

此外,我不得不将evo-inflector从类路径中排除:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.atteo</groupId>
                <artifactId>evo-inflector</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

不是一个很好的解决方案,但它适用于我的设置。

让我们首先确保我们要实现的目标:Spring Data REST公开了两种主要资源:集合资源和项资源。为了能够区分两者,我们需要两个不同的关系名称。因此,默认情况下,Spring Data REST使用项目资源rel的非大写域类名,并使用Evo Inflector库将项目资源rel复数化,并将其用作集合关系名(实际上,您非正式地将其描述为添加s后缀)。

如果手动排除Evo-Inflector库,那么Spring Data REST将返回到集合关系的${itemRel}List,这首先比使用正确的复数名称更麻烦。

正如您已经发现的,您可以手动配置要用于每个存储库的名称但是,将集合资源rel配置为项资源rel是一个非常糟糕的主意,因为这会阻止客户端区分这两种资源类型

假设您已经阅读了这篇文章,并且仍然希望部署一个自定义策略来全局更改类型的关系名称,那么您就可以实现RelProvider(有关实现示例,请参阅EvoInflectorRelProviderDefaultRelProvider)。如果您将该实现注册为Springbean。

@Configuration
class MyConfig {
  @Bean
  YourCustomRelProvider customRelProvider() {
    return new YourCustomRelProvider(…);
  }
}

您可能想要尝试实现的顺序(请参阅@OrderOrdered接口),以确保您的自定义提供程序是选择的,而不是注册的默认提供程序。

最新更新