当前位置: 首页 > 知识库问答 >
问题:

如何在spring-data-hatoas中编写公开资源或资源列表的分页控制器

曹季同
2023-03-14

使用spring-data,我想为我的Person实体编写两个方法。

person.java

public class Person {
    @Id
    String id;
    String name;
    Integer age;
    // getters/setters omitted for clarity
}

我还编写了一个personresouce:

public class PersonResource extends Resource<Person> {

    public PersonResource(Person content, Link... links) {
        super(content, links);
    }

}
public class PersonResourceAssembler extends ResourceAssemblerSupport<Person, PersonResource> {

    public PersonResourceAssembler() {
        super(PersonController.class, PersonResource.class);
    }

    public PersonResource createResource(Person person) {
        PersonResource personResource = new PersonResource(person);
        Link link = linkTo(PersonController.class).slash(person.getId()).withSelfRel();
        personResource.add(link);
        return personResource;
    }

    @Override
    public PersonResource toResource(Person person) {
        PersonResource resource = createResource(person);
        return resource;
    }
}

这是我的PersonController:

@RestController
@RequestMapping("persons")
public class PersonController {

  @Autowired
  private PersonService personService;

  @GetMapping
  public HttpEntity<List<PersonResource>> showAll(@PageableDefault(size = 20) Pageable pageable, PersonDTO condition) {
    Page<Person> page = personService.findAll(pageable, condition);
    Iterable<Person> personList = page.getContent();
    PersonResourceAssembler assembler = new PersonResourceAssembler();
    List<PersonResource> resources = assembler.toResources(personList);
    return new HttpEntity<>(resources);
  }

  @RequestMapping(name = "{id}", produces= MediaType.APPLICATION_JSON_VALUE)
  public HttpEntity<PersonResource> showOne(@PathVariable("id") Long id, PersonDTO condition) {
    condition.setId(id);
    Person person = personService.get(id);
    PersonResourceAssembler assembler = new PersonResourceAssembler();
    PersonResource resource  = assembler.toResource(person);
    return new HttpEntity<>(resource);
  }

}

以下是对列表的响应:

[
  {
    "createdById": 1,
    "createdDate": "2017-09-21T10:21:05.741Z",
    "deleted": false,
    "email": null,
    "firstName": "User49",
    "id": 52,
    "lastModifiedById": null,
    "lastName": "robot",
    "links": [
      {
        "href": "http://localhost:8080/users/52",
        "rel": "self"
      }
    ],
    "middleName": null,
    "mobile": "010101010001149",
    "roleList": [
      {
        "createdById": null,
        "createdDate": "2017-09-21T10:21:05.580Z",
        "deleted": false,
        "id": 2,
        "lastModifiedById": null,
        "name": "USER",
        "userList": null,
        "version": 0
      }
    ],
    "username": "user49",
    "version": 0
  }
]

这是对一个资源的响应:

{
  "_links": {
    "self": {
      "href": "http://localhost:8080/users/52"
    }
  },
  "createdById": 1,
  "createdDate": "2017-09-21T10:21:05.741Z",
  "deleted": false,
  "email": null,
  "firstName": "User49",
  "id": 52,
  "lastModifiedById": null,
  "lastName": "robot",
  "middleName": null,
  "mobile": "010101010001149",
  "roleList": [
    {
      "createdById": null,
      "createdDate": "2017-09-21T10:21:05.580Z",
      "deleted": false,
      "lastModifiedById": null,
      "name": "USER",
      "userList": null
    }
  ],
  "username": "user49"
}
    null

我希望看到使用PagedResource的控制器/汇编程序。

对我来说,解决办法就是这样做

  @GetMapping
  public ResponseEntity<?> findAll(PagedResourcesAssembler<Person> pageAssembler, @PageableDefault(size = 20) Pageable pageable, UserDTO condition) {
    Page<User> userList = userService.findAll(pageable, condition);
    PagedResources<?> resources = pageAssembler.toResource(userList, new UserResourceAssembler());
    return ResponseEntity.ok(resources);
  }

共有1个答案

赵俊晤
2023-03-14

尝试使用PagedResourcesAssembler构建分页资源:

@RestController
@RequestMapping("persons")
public class PersonController {

    @Autowired private PersonService personService;
    @Autowired private PagedResourcesAssembler<Person> assembler;
    @Autowired private EntityLinks links;

    @GetMapping("/paged")
    public ResponseEntity<?> getPaged(Pageable pageable) {
        Page<Person> personsPage = personService.getPaged(pageable);

        Link pageSelfLink = links.linkFor(Person.class).slash("/paged").withSelfRel();
        PagedResources<?> resources = assembler.toResource(personPage, this::toResource, pageSelfLink);

        return ResponseEntity.ok(resources);
    }

    private ResourceSupport toResource(Person person) {
        Link pesonLink = links.linkForSingleResource(person).withRel("person");
        Link selfLink = links.linkForSingleResource(person).withSelfRel();
        return new Resource<>(person, personLink, selfLink);
    }
}

看我的例子。

 类似资料:
  • 资源控制器 资源控制器可以让你轻松的创建RESTFul资源控制器,可以通过命令行生成需要的资源控制器,例如: // 生成index模块的Blog资源控制器 php think make:controller index/Blog 或者使用完整的命名空间生成 php think make:controller app\index\controller\Blog 然后你只需要为资源控制器注册一个资源路

  • 这是一个常用的资源控制器模板,使用时可以复制直接使用,复制后把相应命名空间,类名改掉就可以用了; <?php // +---------------------------------------------------------------------- // | ThinkCMF [ WE CAN DO IT MORE SIMPLE ] // +-----------------------

  • A collection of awesome Ruby libraries, tools, frameworks and software. The essential Ruby to build modern Apps and Web Apps. Inspired by the awesome-* trend on GitHub. The goal is to build a categori

  • 环境:JSF2.1.7Seam2.3.0JBoss5.1.2 我的应用程序有一个需要本地化的字符串 “我同意WorldSite的隐私政策和Cookie通知” 斜体的隐私政策和Cookie通知是指向其他页面的超链接。 最初我们的facets是这样设置的: 注意:我们已经准备好了URL重写,需要/jsf/Notice。xhtml并重写为 这允许对各个键进行零碎的转换 但这需要一些语言的变通方法(在“i

  • 以下资源包含有关Agile Data Science的其他信息。 请使用它们来获得更深入的知识。 关于敏捷数据科学的有用链接 敏捷数据科学 - 敏捷数据科学官方网站 关于敏捷数据科学的有用书籍

  • 当访问下面的URL时,我会得到相应的分页 但是,当访问以下URL时,Spring Data REST没有开箱即用的分页- UserRepository和UserPostRepository都是带有分页的JPA存储库。结果,第二个URL抛出GC开销超出错误,因为返回结果的行数非常大。 有没有办法用第二个URL进行分页?