【问题标题】:HAL links with singular noun instead of plural noun when following rel-links跟随 rel-links 时,HAL 用单数名词而不是复数名词链接
【发布时间】:2019-01-31 11:05:19
【问题描述】:

我正在使用 Spring Boot (2.1.1) 自动创建我的 JpaRepository 接口的 HAL REST API。

在大多数情况下,这些接口是空的,例如:

public interface ProjectRepository extends JpaRepository<Project, Long> {}

public interface ProtocolRepository extends JpaRepository<Protocol, Long> {}

一个Project-entity 包含许多Protocol-entities。 Protocol-entity 有一个指向其Project-entity 的反向链接。

当我访问http://localhost:8080/admin/protocols/4711 时,我得到了它的项目的链接:

...
"project": {
  "href": "http://localhost:8080/admin/protocols/4711/project"
}
...

但是当我点击该链接时,所有其他链接都会生成错误:

  ...
  "_links": {
    "self": {
      "href": "http://localhost:8080/admin/project/1"
    },
    "project": {
      "href": "http://localhost:8080/admin/project/1"
    }
  ...
  }
  ...

链接中的错误是使用了单数名词project,而不是复数形式projects

由于这些链接是自动生成的,因此如何改变这种行为并不明显。

【问题讨论】:

    标签: spring spring-data-rest spring-hateoas hal-json


    【解决方案1】:

    在调试 Spring 内部时,我发现 PersistentEntityResourceAssembler 使用 DefaultSelfLinkProvider 的实例来创建自链接。 当我调试该类时,我意识到当为 Hibernate 代理的对象生成自链接时,它无法正常工作。

    因此我尝试用我自己实现的SelfLinkProvider-interface 替换DefaultSelfLinkProvider

    这可以通过BeanPostProcessor 来完成:

      @Bean
      public BeanPostProcessor entityManagerBeanPostProcessor()
      {
        return new BeanPostProcessor()
        {
          @Override
          public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
          {
            return bean;
          }
    
          @Override
          public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
          {
            if (bean instanceof SelfLinkProvider)
            { return new HibernateSelfLinkProvider((SelfLinkProvider) bean); }
            return bean;
          }
        };
      }
    

    HibernateSelfLinkProviderSelfLinkProvider 的简单包装器:

    public class HibernateSelfLinkProvider implements SelfLinkProvider
    {
      private final SelfLinkProvider selfLinkProvider;
    
      public HibernateSelfLinkProvider(SelfLinkProvider selfLinkProvider)
      {
        this.selfLinkProvider = selfLinkProvider;
      }
    
      @Override
      public Link createSelfLinkFor(Object instance)
      {
        instance = Hibernate.unproxy(instance);
        return selfLinkProvider.createSelfLinkFor(instance);
      }
    }
    

    Hibernate.unproxy() 的好处是它保持给定对象不变,如果它不是代理对象。

    通过这个添加,我得到了正确的链接:"http://localhost:8080/admin/projects/1"。 但我不确定这是否是修改行为的最佳位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-25
      • 2016-04-26
      • 2013-05-21
      • 1970-01-01
      • 2011-10-29
      • 1970-01-01
      相关资源
      最近更新 更多