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

爪哇中的 JSON 补丁请求验证

翁文康
2023-03-14

在我的spring-boot服务中,我使用https://github.com/java-json-tools/json-patch用于处理PATCH请求。

一切似乎都很好,除了一种避免修改不可变字段的方法,如对象ID、creation_time等。我在Github上发现了一个类似的问题https://github.com/java-json-tools/json-patch/issues/21我找不到合适的例子。

这篇博客似乎给出了一些关于使用 node.js 中的解决方案验证 JSON 补丁请求的有趣解决方案。如果知道JAVA中已经存在类似的东西,那就太好了。

共有2个答案

齐涛
2023-03-14

不是直接从客户机接收JsonPatch,而是定义一个DTO来处理验证,然后将DTO实例转换为JsonPatch

假设您想要更新实例< code>User.class的用户,您可以定义一个DTO,例如:

public class UserDTO {

    @Email(message = "The provided email is invalid")
    private String username;

    @Size(min = 2, max = 10, message = "firstname should have at least 2 and a maximum of 10 characters")
    private String firstName;

    @Size(min = 2, max = 10, message = "firstname should have at least 2 and a maximum of 10 characters")
    private String lastName;

    @Override
    public String toString() {
        return new Gson().toJson(this);
    }

//getters and setters
}

自定义toString方法可确保未包含在更新请求中的字段不会预填充null值。

您的 PATCH 请求可以如下所示(为简单起见,我没有满足例外情况)

@PatchMapping("/{id}")
    ResponseEntity<Object> updateUser(@RequestBody @Valid UserDTO request,
                                      @PathVariable String id) throws ParseException, IOException, JsonPatchException {
        User oldUser = userRepository.findById(id);
        String detailsToUpdate = request.toString();
        User newUser = applyPatchToUser(detailsToUpdate, oldUser);
        userRepository.save(newUser);
        return userService.updateUser(request, id);
    }

以下方法返回在控制器中更新的补丁用户。

private User applyPatchToUser(String detailsToUpdate, User oldUser) throws IOException, JsonPatchException {
        ObjectMapper objectMapper = new ObjectMapper();
        // Parse the patch to JsonNode
        JsonNode patchNode = objectMapper.readTree(detailsToUpdate);
        // Create the patch
        JsonMergePatch patch = JsonMergePatch.fromJson(patchNode);
        // Convert the original object to JsonNode
        JsonNode originalObjNode = objectMapper.valueToTree(oldUser);
        // Apply the patch
        TreeNode patchedObjNode = patch.apply(originalObjNode);
        // Convert the patched node to an updated obj
        return objectMapper.treeToValue(patchedObjNode, User.class);
    }
仉昂熙
2023-03-14

在许多情况下,您可以只修补一个中间对象,该对象仅包含用户可以写入的字段。之后,您可以使用一些对象映射器或手动轻松地将中间对象映射到实体。

这样做的缺点是,如果您要求字段必须显式为空,您将不知道补丁对象是否将字段显式设置为null,或者它是否从未出现在补丁中。

你也可以滥用选项来做这件事,例如。

public class ProjectPatchDTO {

    private Optional<@NotBlank String> name;
    private Optional<String> description;
}

虽然Optionals不打算这样使用,但它是在维护输入类型的同时实现补丁操作的最直接的方法。当可选字段为空时,它从未从客户端传递。当可选项不存在时,这意味着客户端已将该值设置为null。

 类似资料:
  • 有没有办法在spring boot中验证补丁请求主体? 如果任何用户发送请求时,“op”(字段)为“xx”,而“path”(字段)为“se”。有没有办法在不更改合同的情况下验证它并抛出400(错误的请求)?

  • 我刚刚开始从我现有的网络库移植到Android的Volley。到目前为止,我已经成功地实现了适用的Volleys ImageLoader。现在,我试图让我的第一个超文本传输协议调用和运行,但我发现这个错误。 注意:我有意以补丁请求开始,因为我将经常使用它们。另外,我的版本Volley也支持补丁:https://android.googlesource.com/platform/frameworks

  • 如何在Laravel中验证补丁/放置请求 根据Laravel留档http://laravel.com/docs/5.1/controllers,请求由资源控制器的操作处理 由于请求应更新部分资源并将更新整个资源,因此我的 验证应如下所示: 我应该这样做吗 依靠您的专业答案。

  • 问题内容: 我正在使用djang-tastypie作为后端和AngularJs作为前端的API。我正在使用angularjs $ http从CRUD发送请求。GET,POST,PUT一切都很好,但是当我尝试发送PATCH请求时,出现错误,未定义PATCH方法。我已经在angular中创建了一个api调用工厂,但是PATCH请求在那里不起作用。 这是我的HTML代码 当我在控制台中使用此代码发送路径

  • 我正在使用Symfony2开发一个REST API。我有一个预订系统,我想发送电子邮件给一个客户时,他的预订是由管理员验证。 我有一个预订重新源,我们可以使用以下url验证预订: 修补localhost/:id/validate

  • 我目前正在制作一个拉丁方块,以用户设置的数字开始,但为了简单起见,我将排除扫描仪代码。 它打印出来: 它是如此接近,考虑到事实,它确实从我预先确定的第一个数字开始,它只打印4个整数。我遇到的问题是,它比我的顺序整数走得更远,而且它打印的行数是双倍。你知道我能做些什么来解决这个问题吗?