来自 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;
    }
}

然后在我的浏览器中输入

http://localhost:8080/anna_n/subjects

有谁知道我做错了什么?谢谢/米克

首先让我们从一个示例开始,与您的代码进行比较:

@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