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

带补丁方法的Spring Data Rest自定义控制器-如何将资源与实体合并

贺海
2023-03-14

默认情况下,当我们公开了保存方法的存储库时,我们可以执行PATCH请求。然后Spring Data REST从数据库中检索原始对象并将更改应用于实体,然后为我们保存它(在JsonPatchHandler类中)。这允许我们对类执行以下请求

class Address {
     Long id;
     String street;
     Long houseNumber;
}

PATCH/api/addresss/1和正文

{ houseNumber: 123 }

只有这一个领域会被改变。

现在有了自定义控制器,我们希望在更新方法中接收整个对象(在HATEOAS将其与数据库中的原始对象合并后)

@RepositoryRestController
@ExposesResourceFor(Address.class)
@ResponseBody
@RequestMapping("/addresses")
public class AdddressController {

    @PatchMapping("/{addressId}")
    public Resource<Address> update(@RequestBody Resource<Address> addressResource, @PathVariable Long addressId) {
        Address address= addressResource.getContent();
        // .... some logic
        address = addressRepository.save(address);
        return new Resource<>(address);
    }
}

不幸的是,在我要做一些逻辑的地方,我得到了空字段的地址,而不是合并的对象。

是否可以将自定义控制器插入SpringDataREST堆栈中,以便在修补请求时,它将为我合并它(就像普通存储库一样)?

编辑:我想找到一个既能透明地处理补丁(内容类型:应用程序/json-补丁JSON)又能透明地处理补丁(内容类型:应用程序/hal json)的解决方案

共有1个答案

长孙谦
2023-03-14

在浏览了Spring源代码之后,我还没有找到一个合理的解决方案。因此,我在他们的-JIRA中制造了问题

目前,唯一合理的解决方法是创建自定义控制器,将PersitentEntityResource作为参数,并在其路径中包含{id}和{repository}占位符,即

@PatchMapping("/addresses/{id}/{repository}")
public Resource<Address> update(PersistentEntityResource addressResource) {
    ...
}

这使得调用endpoint/地址/123/地址

 类似资料:
  • 使用JSONAPI1.0标准设计API,没有PUT方法。只有用于创建资源的POST方法和用于部分更新的修补程序。我们有这样的用例:用户可以向服务器发送请求,如果资源不存在,则必须创建资源,否则必须更新资源。RFC将这种方法描述为PUT。接下来引用提到的RFC5789标准补丁有信息: “如果Request-URI没有指向现有资源,服务器可能会创建一个新资源,具体取决于补丁文档类型(是否可以在逻辑上修

  • 我尝试用自定义控制器制作一个自定义组件。自定义组件已经显示在应用程序上,但我未能向其添加属性。 项目结构: null 布尔马尔科 完全错误: 原因:java.lang.nullPointerException:无法调用“javafx.scene.image.imageeview.setimage(javafx.scene.image.image)”,因为“controller.topbarbtn.

  • 当我尝试点击具有方法的请求时,我收到以下错误:PATCH 使用JMeter版本:-apache-JMeter-5.4.1 如果我能得到专家的帮助来解决他们的问题,那将会很有帮助。 谢谢

  • 资源控制器 资源控制器可以让你轻松的创建RESTFul资源控制器,可以通过命令行生成需要的资源控制器,例如: // 生成index模块的Blog资源控制器 php think make:controller index/Blog 或者使用完整的命名空间生成 php think make:controller app\index\controller\Blog 然后你只需要为资源控制器注册一个资源路

  • 自定义路由 easySwoole支持路由拦截。其路由利用fastRoute实现,因此其路由规则与其保持一致,该组件的详细文档请参考 GitHub文档 路由定义 若需要再easySwoole使用路由拦截功能,请在应用目录(默认为App)下,建立Router类,井继承Core\AbstractInterface\AbstractRouter实现addRouter方法,如果在类UNIX系统下请严格注意文

  • 我正在使用Jersey创建RESTful API。我想通过Accept头实现版本控制。我的资源(例如MyResourceV1、MyResourceV2和SubresourceV1、SubresourceV2)被分为不同的类。现在,我使用的是内容类型