1

基于示例项目 https://github.com/jcoig/gs-accessing-data-rest 中的https://spring.io/guides/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
  }
}

我不想persons在 URL中有,也不想persons在返回的 JSON 中作为键。当然,我可以如下定义我的存储库:

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

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

4

2 回答 2

2

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

@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>

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

于 2014-10-14T09:00:35.227 回答
1

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

如果您手动排除 Evo Inflector 库,则 Spring Data REST 会回退到${itemRel}List集合关系,这首先比使用正确的复数名称更笨拙。

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

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

@Configuration
class MyConfig {

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

您可能想试验实现的顺序(参见@OrderOrdered接口),以确保选择您的自定义提供程序以支持注册的默认提供程序。

于 2014-09-25T17:23:27.790 回答