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

Spring Hateoas ControllerLinkBuilder添加空字段

柯翔
2023-03-14

我正在学习关于Spring REST的教程,并试图将HATEOAS链接添加到我的控制器结果中。

我有一个简单的User类和一个CRUD控制器。

class User {
    private int id;
    private String name;
    private LocalDate birthdate;
    // and getters/setters
}

服务:

@Component
class UserService {
    private static List<User> users = new ArrayList<>();
    List<User> findAll() {
        return Collections.unmodifiableList(users);
    }
    public Optional<User> findById(int id) {
        return users.stream().filter(u -> u.getId() == id).findFirst();
    }
    // and add and delete methods of course, but not important here
}

一切正常,除了在我的控制器中,我想将所有用户列表中的链接添加到单个用户:

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;

@RestController
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping("/users")
    public List<Resource<User>> getAllUsers() {
        List<Resource<User>> userResources = userService.findAll().stream()
            .map(u -> new Resource<>(u, linkToSingleUser(u)))
            .collect(Collectors.toList());
        return userResources;
    }
    Link linkToSingleUser(User user) {
        return linkTo(methodOn(UserController.class)
                      .getById(user.getId()))
                      .withSelfRel();
    }

因此,对于结果列表中的每个用户,都会添加指向用户本身的链接。

链接本身创建得很好,但生成的JSON中有多余的条目:

[
    {
        "id": 1,
        "name": "Adam",
        "birthdate": "2018-04-02",
        "links": [
            {
                "rel": "self",
                "href": "http://localhost:8080/users/1",
                "hreflang": null,
                "media": null,
                "title": null,
                "type": null,
                "deprecation": null
            }
        ]
    }
]

空值字段(hreflangmedia等)来自何处,为什么要添加这些字段?有没有办法摆脱它们?

在构建指向所有用户列表的链接时,它们不会出现:

@GetMapping("/users/{id}")
public Resource<User> getById(@PathVariable("id") int id) {
    final User user = userService.findById(id)
                                 .orElseThrow(() -> new UserNotFoundException(id));
    Link linkToAll = linkTo(methodOn(UserController.class)
                            .getAllUsers())
                            .withRel("all-users");
    return new Resource<User>(user, linkToAll);
}

共有3个答案

史逸春
2023-03-14

根据Spring HATEOAS#493,“因为您的顶层结构不是有效的HAL结构,因此绕过了HAL序列化程序。”

要解决此问题,请使用:

return new Resources<>(assembler.toResources(sourceList));
督烨赫
2023-03-14

正如semiintel所提到的,问题在于列表返回对象不是有效的HAL类型:

public List<Resource<User>> getAllUsers()

通过将返回类型更改为以下资源,可以轻松解决这一问题:

public Resources<Resource<User>> getAllUsers()

然后,您可以简单地包装您的资源

return userResources;

收件人:

return new Resources<>(userResources)

然后,您应该像对待单个对象那样获得适当的链接序列化。

此方法由这篇非常有用的文章提供,用于解决此问题:

https://www.logicbig.com/tutorials/spring-framework/spring-hateoas/multiple-link-relations.html

潘宪
2023-03-14

为了进一步参考,以防其他人偶然发现这一点,我找到了答案:我在应用程序中添加了一个条目。属性,即

spring.jackson.default-property-inclusion=NON_NULL

为什么这对于Link对象是必要的,但对于User我不知道(并且还没有深入研究)。

 类似资料:
  • 我正在尝试添加一个表单内的多种颜色的选项。问题是,即使在添加了一个在第一个颜色字段下面添加一个新字段的按钮之后,后续字段也不会保存在jQuery调用和PHP控制器上的dd()中。 供参考 以下是点击submit后我得到的信息。

  • 问题内容: 我有一个正在创建的字符串,并且需要向该字符串添加多个“ \ 0”(空)字符。在每个空字符之间是其他文本数据(仅ASCII字母数字字符)。 我的问题是,在J2SE中,当您添加第一个null(\ 0)时,java似乎确定它是一个字符串终止符(类似于C ++),并且忽略了所有附加的数据。不引发错误,尾随的数据将被忽略。我需要在字符串中的null后强制添加其他尾随数据。我必须对我支持的旧数据库

  • 我正在解构一个Java对象,从getter中获取所有必需的String值,并将所有这些值连接到每个对象的一个String中。然后我想存储每个字符串是 我将字符串连接到每个对象的一个字符串中,这样我就可以将其打印到pdf文档(pdfbox)中以生成报告。。。我想将每一行的格式设置为与表中的相同。E、 g不管String1是3个字符还是103个字符长,它都将始终填充25个字符的空间——要么子字符串变小

  • 问题内容: 我有一个最大字符范围为16的字符,每4个字符后,我要添加一个负字符或空格,然后编写其余的字符,例如本示例5022-2222-2222-2222。有我的代码,但是那不起作用,该怎么办? 我在 范围方法中添加此代码。 问题答案: 我们可以从实现oisdk:s SwiftSequence 方法的(版本号)的Swift 3版本开始: 在这种情况下,实现自定义格式是创建4个字符的块并将其通过“-

  • 如何在div之间添加垂直空间。这里是否可以添加引导类?有什么帮助吗? 下面是我的代码片段:

  • 问题内容: 我有这个android代码,它从服务器中获取一个JSON并从该JSON填充一个ArrayList,我在onresponse空隙内检查了ArrayList“ meals”的大小,它给了我1,但是当我在StringRequest对象后对其进行检查时,我得到了0个项目。进餐在全局范围内定义,并在oncreateview函数内部进行初始化代码: 问题答案: 这里的问题是关于了解任务如何工作的。