来自 Hateoas 的资源响应 Spring 引导显示 Whitelabel 错误页面
Resource-response from Hateoas Spring Boot shows Whitelabel Error Page
我不是专业的 Spring 引导开发人员。我在教程的帮助下编写了一个程序,我正在使用 Hateoas 和 Rest,当我从请求返回响应时,我得到一个 whitelabel 错误页面。
当我尝试使用 System.out.println() 写入值时,资源对象本身看起来是正确的。
这是 RestController 方法。
@RequestMapping(method = RequestMethod.GET ,produces = {MediaType.APPLICATION_JSON_VALUE, "application/hal+json"})
Resources<SubjectResource> readSubject(@PathVariable String userId) {
this.validateUser(userId);
List<SubjectResource>subjectResource=subjectRepository.findByTeacherUsername(userId).stream().map(SubjectResource:: new).collect(Collectors.toList());
Resources <SubjectResource>r=new Resources<>(subjectResource);
return new Resources<>(subjectResource);
}
这是我在 RestController 中使用的导入-class
import java.net.URI;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.hateoas.Link;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.Resources;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
这是资源文件
import org.springframework.hateoas.Link;
进口org.springframework.hateoas.ResourceSupport;
导入静态 org.springframework.hateoas.mvc.ControllerLinkBuilder.*;
class SubjectResource extends ResourceSupport {
private final Subject subject;
public SubjectResource(Subject subject) {
String username = subject.getTeacher().getUsername();
this.subject = subject;
this.add(new Link(subject.uri, "subject-uri"));
this.add(linkTo(SubjectRestController.class, username).withRel("subjects"));
this.add(linkTo(
methodOn(SubjectRestController.class, username).readSubject(username,
subject.getId())).withSelfRel());
}
public Subject getSubject() {
return subject;
}
}
然后在我的浏览器中输入
有谁知道我做错了什么?谢谢/米克
首先让我们从一个示例开始,与您的代码进行比较:
@RestController
@ExposesResourceFor(Booleans.class)
@RequestMapping("/booleans")
public class BooleansController {
public static final String TRUE = "true";
public static final String FALSE = "false";
public static final String TRUEFALSE = "truefalse";
@Autowired
private EntityLinks entityLinks;
@RequestMapping(value = "/{booleansId}",
produces = { "application/hal+json", "application/json" },
method = RequestMethod.GET)
public ResponseEntity<Booleans> getBooleans(@PathVariable("booleansId") String booleansId) {
return getResource(booleansId)
.map(r -> new ResponseEntity<>(r, HttpStatus.OK))
.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
private Optional<Booleans> getResource(String id) {
switch (id) {
case TRUE:
final Booleans trueInstance = new Booleans().addValuesItem(true);
trueInstance.add(entityLinks.linkToSingleResource(Booleans.class, TRUE));
return Optional.of(trueInstance);
case FALSE:
final Booleans falseInstance = new Booleans().addValuesItem(false);
falseInstance.add(entityLinks.linkToSingleResource(Booleans.class, FALSE));
return Optional.of(falseInstance);
case TRUEFALSE:
final Booleans truefalseInstance = new Booleans().addValuesItem(true).addValuesItem(false);
truefalseInstance.add(entityLinks.linkToSingleResource(Booleans.class, TRUEFALSE));
return Optional.of(truefalseInstance);
default:
return Optional.empty();
}
}
}
以及资源:
public class Booleans extends ResourceSupport {
@JsonProperty("values")
private List<Boolean> values = new ArrayList<Boolean>();
public Booleans addValuesItem(Boolean valuesItem) {
this.values.add(valuesItem);
return this;
}
public List<Boolean> getValues() {
return values;
}
public void setValues(List<Boolean> values) {
this.values = values;
}
}
尝试卷曲:
curl "http://localhost:8085/myapp/booleans/truefalse"
{
"_links": {
"self": {
"href": "http://localhost:8085/myapp/booleans/truefalse"
}
},
"values": [
true,
false
]
}
一个显着的区别是 @RequestMapping(value = "/{booleansId}",
,您的代码中缺少它。那是我的第一个赌注。尝试 @RequestMapping(value = "/{userId}/subjects"
我已更新此答案以使用 EntityLinks 和 @ExposesResourceFor 注释以及 class 和方法级别 @RequestMapping 来演示如何确保资源的正确 JSON HAL 链接。有关构建适当资源的方法,请参阅 ResourceAssemblerSupport
。
我不是专业的 Spring 引导开发人员。我在教程的帮助下编写了一个程序,我正在使用 Hateoas 和 Rest,当我从请求返回响应时,我得到一个 whitelabel 错误页面。
当我尝试使用 System.out.println() 写入值时,资源对象本身看起来是正确的。
这是 RestController 方法。
@RequestMapping(method = RequestMethod.GET ,produces = {MediaType.APPLICATION_JSON_VALUE, "application/hal+json"})
Resources<SubjectResource> readSubject(@PathVariable String userId) {
this.validateUser(userId);
List<SubjectResource>subjectResource=subjectRepository.findByTeacherUsername(userId).stream().map(SubjectResource:: new).collect(Collectors.toList());
Resources <SubjectResource>r=new Resources<>(subjectResource);
return new Resources<>(subjectResource);
}
这是我在 RestController 中使用的导入-class
import java.net.URI;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.hateoas.Link;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.Resources;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
这是资源文件
import org.springframework.hateoas.Link;
进口org.springframework.hateoas.ResourceSupport; 导入静态 org.springframework.hateoas.mvc.ControllerLinkBuilder.*;
class SubjectResource extends ResourceSupport {
private final Subject subject;
public SubjectResource(Subject subject) {
String username = subject.getTeacher().getUsername();
this.subject = subject;
this.add(new Link(subject.uri, "subject-uri"));
this.add(linkTo(SubjectRestController.class, username).withRel("subjects"));
this.add(linkTo(
methodOn(SubjectRestController.class, username).readSubject(username,
subject.getId())).withSelfRel());
}
public Subject getSubject() {
return subject;
}
}
然后在我的浏览器中输入
有谁知道我做错了什么?谢谢/米克
首先让我们从一个示例开始,与您的代码进行比较:
@RestController
@ExposesResourceFor(Booleans.class)
@RequestMapping("/booleans")
public class BooleansController {
public static final String TRUE = "true";
public static final String FALSE = "false";
public static final String TRUEFALSE = "truefalse";
@Autowired
private EntityLinks entityLinks;
@RequestMapping(value = "/{booleansId}",
produces = { "application/hal+json", "application/json" },
method = RequestMethod.GET)
public ResponseEntity<Booleans> getBooleans(@PathVariable("booleansId") String booleansId) {
return getResource(booleansId)
.map(r -> new ResponseEntity<>(r, HttpStatus.OK))
.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
private Optional<Booleans> getResource(String id) {
switch (id) {
case TRUE:
final Booleans trueInstance = new Booleans().addValuesItem(true);
trueInstance.add(entityLinks.linkToSingleResource(Booleans.class, TRUE));
return Optional.of(trueInstance);
case FALSE:
final Booleans falseInstance = new Booleans().addValuesItem(false);
falseInstance.add(entityLinks.linkToSingleResource(Booleans.class, FALSE));
return Optional.of(falseInstance);
case TRUEFALSE:
final Booleans truefalseInstance = new Booleans().addValuesItem(true).addValuesItem(false);
truefalseInstance.add(entityLinks.linkToSingleResource(Booleans.class, TRUEFALSE));
return Optional.of(truefalseInstance);
default:
return Optional.empty();
}
}
}
以及资源:
public class Booleans extends ResourceSupport {
@JsonProperty("values")
private List<Boolean> values = new ArrayList<Boolean>();
public Booleans addValuesItem(Boolean valuesItem) {
this.values.add(valuesItem);
return this;
}
public List<Boolean> getValues() {
return values;
}
public void setValues(List<Boolean> values) {
this.values = values;
}
}
尝试卷曲:
curl "http://localhost:8085/myapp/booleans/truefalse"
{
"_links": {
"self": {
"href": "http://localhost:8085/myapp/booleans/truefalse"
}
},
"values": [
true,
false
]
}
一个显着的区别是 @RequestMapping(value = "/{booleansId}",
,您的代码中缺少它。那是我的第一个赌注。尝试 @RequestMapping(value = "/{userId}/subjects"
我已更新此答案以使用 EntityLinks 和 @ExposesResourceFor 注释以及 class 和方法级别 @RequestMapping 来演示如何确保资源的正确 JSON HAL 链接。有关构建适当资源的方法,请参阅 ResourceAssemblerSupport
。