如何将模板化的selfrel添加到Spring HATEOAS PagedResourcesAssembler?

时间:2016-09-12 10:27:09

标签: spring spring-hateoas

我目前正在使用spring hateoas构建API。我的大多数控制器都提供了一个返回PagedResources<>的列表方法。由于某种原因,selfrel不包含在所有示例中找到的www模板。相反,我只获得基本URI。

所以我的...我的ProjectContoller看起来像

{?page,size,sort}

并返回

@GetMapping
public PagedResources<ProjectResource> list(Pageable pageable, PagedResourcesAssembler<Project> pagedResourcesAssembler){
    Page<Project> projects = service.findAll(pageable);
    return pagedResourcesAssembler.toResource(projects, assembler);
}

我想我错过了一些微不足道的东西但却找不到: - /

1 个答案:

答案 0 :(得分:0)

在阅读HAL应如何在Spring Data Rest中表现后,似乎可能存在一些错误。

这是links集合资源的标准Spring Data Rest tasks输出:

 "_links": {
    "first": {
      "href": "http://localhost:8080/tasks?page=0&size=20"
    },
    "self": {
      "href": "http://localhost:8080/tasks"
    },
    "next": {
      "href": "http://localhost:8080/tasks?page=1&size=20"
    },
    "last": {
      "href": "http://localhost:8080/tasks?page=2&size=20"
    },
    "profile": {
      "href": "http://localhost:8080/profile/tasks"
    },
    "search": {
      "href": "http://localhost:8080/tasks/search"
    }

Spring Data Rest提供的开箱即用的HAL响应中没有模板链接,与文档中显示的相反。

如果我关注next链接,则self链接不正确:

"_links": {
    "first": {
      "href": "http://localhost:8080/tasks?page=0&size=20"
    },
    "prev": {
      "href": "http://localhost:8080/tasks?page=0&size=20"
    },
    "self": {
      "href": "http://localhost:8080/tasks"
    },
    "next": {
      "href": "http://localhost:8080/tasks?page=2&size=20"
    },
    "last": {
      "href": "http://localhost:8080/tasks?page=2&size=20"
    },
    "profile": {
      "href": "http://localhost:8080/profile/tasks"
    },
    "search": {
      "href": "http://localhost:8080/tasks/search"
    }
  }

如果我覆盖Controller:

@RequestMapping(method = RequestMethod.GET, path = "/tasks")
    public ResponseEntity<Page<Task>> read(Pageable pageRequest, PersistentEntityResourceAssembler assembler) {
        Page<Task> pendingTasks = taskService.read(pageRequest);
        return new ResponseEntity(pageAssembler.toResource(pendingTasks, (ResourceAssembler) assembler),
                                  HttpStatus.OK);
    }

在控制器和存储库之间添加一个服务,即使没有指定,也会将Pageable实例初始化为默认值:

 public Page<Task> read(Pageable pageRequest) {
        Pageable effectivePageRequest = pageRequest;
        if (effectivePageRequest == null) {
            effectivePageRequest = new PageRequest(0, 20, DEFAULT_SORT);
        }
        if (effectivePageRequest.getSort() == null) {
            //override Sort
            effectivePageRequest = new PageRequest(effectivePageRequest.getPageNumber(),
                                                   effectivePageRequest.getPageSize(), DEFAULT_SORT);
        }
        return taskRepository.findByStatus(Task.Status.PENDING, effectivePageRequest);
    }

我可以使用self链接解决问题。但是看不到生成模板化URI的方法。这些是第二页的链接:

"_links": {
    "first": {
      "href": "http://localhost:8080/tasks?page=0&size=20&sort=created,desc"
    },
    "prev": {
      "href": "http://localhost:8080/tasks?page=0&size=20&sort=created,desc"
    },
    "self": {
      "href": "http://localhost:8080/tasks?page=1&size=20&sort=created,desc"
    },
    "next": {
      "href": "http://localhost:8080/tasks?page=2&size=20&sort=created,desc"
    },
    "last": {
      "href": "http://localhost:8080/tasks?page=2&size=20&sort=created,desc"
    }

希望这有助于丢弃可能性,但此处显示的默认行为表明在生成集合链接时Spring HATEOAS / Spring Data Rest可能存在一些问题。

我使用org.springframework.boot:spring-boot-starter-data-rest:jar:1.4.0.RELEASEorg.springframework.data:spring-data-rest-webmvc:jar:2.5.2.RELEASEorg.springframework.hateoas:spring-hateoas:jar:0.20.0.RELEASE