使用spring hateoas

时间:2016-10-20 13:51:02

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

我有同样的问题(Exposing link on collection entity in spring data REST)。但该主题没有任何内容可以帮助我添加自定义链接到收集调用。

@Component
public class EventListResourceProcessor implements ResourceProcessor<Resources<Event>> {

    @Autowired
    private RepositoryEntityLinks entityLinks;

    @Override
    public Resources<Event> process(Resources<Event> events) {
        events.add(entityLinks.linkToCollectionResource(Event.class).withRel("events"));
        return events;
    }
}
在这种情况下,永远不会调用

过程方法。

我需要调用http://localhost:8080/event并在_links部分下使用my_custom_link获取以下JSON:

&#13;
&#13;
{
  "_embedded": {
    "event": [
      {
        "id": "1",
        "name": "Updated event"
      }]
  },
  "_links": {
    "self": {
      "href": "http://localhost:8080/event"
    },
    "profile": {
      "href": "http://localhost:8080/profile/event"
    },
    "my_custom_link": {
      "href": "http://localhost:8080/custom/"
    }
  },
  "page": {
    "size": 20,
    "totalElements": 4,
    "totalPages": 1,
    "number": 0
  }
}

}
&#13;
&#13;
&#13;

你可以告诉我吗?

提前致谢!

2 个答案:

答案 0 :(得分:1)

我的问题与你的问题类似:我已经阅读了你链接的问题/答案,发现没有一个能解决问题。这是我的问题的最终答案:

@Component
public class MyResourceProcessor implements ResourceProcessor<Resource<MyInterface>> {

    @Autowired
    private EntityLinks entityLinks;

    @Override
    public Resource<MyInterface> process(Resource<MyInterface> event) {
        event.add(entityLinks.linkForSingleResource(MyClass.class, event.getContent().getId()).slash("custom").withRel("custom"));
        return event;
    }
}

为返回的相关资源集合中的每个资源调用此process方法。 MyInterface接口和MyClass类应该替换为您最终需要的任何内容,但是必须以这种方式编写才能使其工作。以下是我用于正确调用process方法并确定MyInterface类型的步骤。

  1. 我创建了一个process方法,只需将ResourceSupport作为参数。我在代码中创建了一个断点,并检查了基础类扩展了什么ResourceSupport。就我而言,它是PersistentEntityResource。这解释了为什么使用Resource<MyClass>Resources<MyClass>永远不会导致调用process方法:PersistentEntityResource扩展Resource<Object>

  2. 我更新了process方法取PersistentEntityResource作为参数。这导致调用process方法的次数超过我的预期更改。我再次使用断点检查PersistentEntityResource对象,目的是发现在Resource<Object>扩展的类中找到了哪个类。我发现它是一个Proxy类,无法按照我的意愿投射到MyClass

  3. 我按照此处的答案查找了有关Proxy课程的更多信息:https://stackoverflow.com/a/3344386/1417690。在调试时,我发现了帮助定义此类的接口列表。其中一个是MyProjectionInterface类型。我现在知道我无法使用Resource<Portal>的原因是因为它实际上是Resource<MyProjectionInterface>

  4. 我需要处理三个不同的Projections。我没有创建三个单独的ResourcePorcoessors,而是创建了MyInterface,并且我的所有三个projection接口都扩展了它。 MyInterface仅包含Long getId()方法,无论如何都已支持所有projections

  5. 我更新了我的代码以使用Resource<MyInterface>,并使用linkForSingleResource(所有MyClass都与之相关)和{{1}添加了projections我在getId()中定义的方法。这成功地为所返回的每个资源添加了所需的链接。

  6. 希望这些步骤可以帮助其他人了解如何确定要用作MyInterface方法参数的类型。

答案 1 :(得分:0)

因为我遇到了同样的问题,所以希望在这里得到答案。解决方案是声明一个bean ResourceProcessor,该bean实现扩展了ResourceSupport的正确通用类型。

在我们针对分页资源的情况下,权利ResourceSupportPagedResources<Resource<MyInterface>>,如下例所示:

@Bean
public ResourceProcessor<PagedResources<Resource<Supplier>>> pageableSupplierProcessor() {
    return new ResourceProcessor<PagedResources<Resource<Supplier>>>() {
        @Override
        public PagedResources<Resource<Supplier>> process(PagedResources<Resource<Supplier>> resources) {
            Method registerMethod;
            try {
                registerMethod = SupplierRegistrationController.class.getMethod("register",
                        RegistrationRequest.class);
                Link registerLink = linkTo(registerMethod, new RegistrationRequest()).withRel("register");
                resources.add(registerLink);
                return resources;
            } catch (NoSuchMethodException | SecurityException e) {
                throw new IllegalStateException(e);
            }
        }
    };
}