Sprint Boot REST HATEOAS服务中的实体输出不起作用。该服务为每个实体返回一个空字符串。没有错误消息。我试过Spring Boot 1.5.4和2.0.0.RC1。
完整的源代码在GitHub上:https://github.com/murygin/hateoas-people-service
应用
@SpringBootApplication
@Configuration
@EnableHypermediaSupport(type={EnableHypermediaSupport.HypermediaType.HAL})
public class Application {
public static void main(String args[]) {
SpringApplication.run(Application.class);
}
}
PersonController
@RestController
@RequestMapping(value = "/persons", produces = "application/hal+json")
public class PersonController {
@GetMapping
public ResponseEntity<Resources<PersonResource>> all() {
final List<PersonResource> collection =
getPersonList().stream().map(PersonResource::new).collect(Collectors.toList());
final Resources<PersonResource> resources = new Resources<>(collection);
final String uriString = ServletUriComponentsBuilder.fromCurrentRequest().build().toUriString();
resources.add(new Link(uriString, "self"));
return ResponseEntity.ok(resources);
}
@GetMapping("/{id}")
public ResponseEntity<PersonResource> get(@PathVariable final long id) {
Person p = new Person((long)1,"Donald","Duck");
return ResponseEntity.ok(new PersonResource(p));
}
private List<Person> getPersonList() {
List<Person> personList = new LinkedList<>();
personList.add(new Person((long)1,"Donald","Duck"));
personList.add(new Person((long)2,"Dagobert","Duck"));
personList.add(new Person((long)3,"Daniel","Duesentrieb"));
return personList;
}
}
PersonResource
public class PersonResource extends ResourceSupport {
private final Person person;
public PersonResource(final Person person) {
this.person = person;
final long id = person.getId();
add(linkTo(PersonController.class).withRel("people"));
add(linkTo(methodOn(PersonController.class).get(id)).withSelfRel());
}
}
人
public class Person {
private Long id;
private String firstName;
private String secondName;
public Person() {
}
public Person(Long id, String firstName, String secondName) {
this.id = id;
this.firstName = firstName;
this.secondName = secondName;
}
// getter and setter...
}
的输出
{
_embedded: {
personResourceList: [{
_links: {
people: {
href: "http://localhost:8080/persons"
},
self: {
href: "http://localhost:8080/persons/1"
}
}
},
{
_links: {
people: {
href: "http://localhost:8080/persons"
},
self: {
href: "http://localhost:8080/persons/2"
}
}
},
{
_links: {
people: {
href: "http://localhost:8080/persons"
},
self: {
href: "http://localhost:8080/persons/3"
}
}
}
]
},
_links: {
self: {
href: "http://localhost:8080/persons"
}
}
}
http://localhost:8080/persons/1
的输出 {
_links: {
people: {
href: "http://localhost:8080/persons"
},
self: {
href: "http://localhost:8080/persons/1"
}
}
}
答案 0 :(得分:1)
在PersonResource中为person添加一个getter:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" ></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
<div class="container">
<div class="">
<div class="float-left">div 1</div>
<div class="float-right">div end</div>
</div>
</div>
使用getter,Spring会获取PersonResource中包含的人并对其进行序列化:
获取http://localhost:8080/persons/1
public class PersonResource extends ResourceSupport {
private final Person person;
public PersonResource(final Person person) {
this.person = person;
final long id = person.getId();
add(linkTo(PersonController.class).withRel("people"));
add(linkTo(methodOn(PersonController.class).get(id)).withSelfRel());
}
public Person getPerson() {
return person;
}
}
获取http://localhost:8080/persons
{
"person" : {
"id" : 1,
"firstName" : "Donald",
"secondName" : "Duck"
},
"_links" : {
"people" : {
"href" : "http://localhost:8080/persons"
},
"self" : {
"href" : "http://localhost:8080/persons/1"
}
}
}
注意:我是一个懒惰的流浪汉,我将spring-boot-starter-data-rest添加到pom.xml依赖项中以便打印结果,因此您的实际结果可能会有所不同。
答案 1 :(得分:1)
我建议您使用资源而不是 ResourceSupport 的扩展,为您的案例采用非常少侵入性的方法。你的代码看起来像这样:
@RestController
@RequestMapping(value = "/persons", produces = "application/hal+json")
public class PersonController {
@GetMapping
public ResponseEntity<List<Resource<Person>>> all() {
final List<Resource<Person>> collection =
getPersonList().stream()
.map(p -> new Resource<>(p, this.getLinks(p.getId())))
.collect(Collectors.toList());
return ResponseEntity.ok(collection);
}
@GetMapping("/{id}")
public ResponseEntity<Resource<Person>> get(@PathVariable final long id) {
Person p = new Person(id,"Donald","Duck");
Resource<Person> resource = new Resource<>(p, this.getLinks(id));
return ResponseEntity.ok(resource);
}
private List<Person> getPersonList() {
List<Person> personList = new LinkedList<>();
personList.add(new Person((long)1,"Donald","Duck"));
personList.add(new Person((long)2,"Dagobert","Duck"));
personList.add(new Person((long)3,"Daniel","Duesentrieb"));
return personList;
}
private List<Link> getLinks(long id) {
return Arrays.asList(
linkTo(PersonController.class).withRel("people"),
linkTo(methodOn(getClass()).get(id)).withSelfRel());
}
}
输出更清晰:
获取http://localhost:8080/persons/1
{
"id": 1,
"firstName": "Donald",
"secondName": "Duck",
"_links": {
"people": {"href": "http://localhost:8080/persons"},
"self": {"href": "http://localhost:8080/persons/1"}
}
}
获取http://localhost:8080/persons
[
{
"id": 1,
"firstName": "Donald",
"secondName": "Duck",
"_links": {
"people": {"href": "http://localhost:8080/persons"},
"self": {"href": "http://localhost:8080/persons/1"}
}
},
{
"id": 2,
"firstName": "Dagobert",
"secondName": "Duck",
"_links": {
"people": {"href": "http://localhost:8080/persons"},
"self": {"href": "http://localhost:8080/persons/2"}
}
},
{
"id": 3,
"firstName": "Daniel",
"secondName": "Duesentrieb",
"_links": {
"people": {"href": "http://localhost:8080/persons"},
"self": {"href": "http://localhost:8080/persons/3"}
}
}
]
只是另一种观点,希望这会有所帮助。