结合@PathVariable 和@RequestBody

Mat*_*vic 7 java spring spring-mvc spring-boot

我有一个DTO

public class UserDto {
  private Long id;
  private String name;
}
Run Code Online (Sandbox Code Playgroud)

Controller

@RestController
@RequestMapping("user")
public Class UserController {
  @PostMapping(value = "{id}")
  public String update(@PathVariable String id, @RequestBody UserDto userDto){
    userDto.setId(id);
    service.update(userDto);
  }
}
Run Code Online (Sandbox Code Playgroud)

我不喜欢手动放置IDfrom @PathVariableto DTO: userDto.setId(id);

对于/user/5带有 body: 的POST 请求,{ name: "test" }我如何自动设置IDin DTO,以便您获得DTO如下效果?

{
  id: 5,
  name: "test"
}
Run Code Online (Sandbox Code Playgroud)

基本上,我想要这样的东西:

{
  id: 5,
  name: "test"
}
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

谢谢!:)

编辑:这是一个老问题,仍然没有答案,所以我想为这个问题添加新的观点。

我们遇到的另一个问题是验证,针对特定定义的自定义约束,该约束基于某些字段和id.

如果我们id从请求正文中删除,那么我们如何从自定义约束中访问它?:)

lma*_*arx 12

该端点似乎正在执行更新操作,所以让我们退后两步。

PUT请求用于更新单个资源,最佳实践是POST优先PUT选择创建(至少是顶级)资源。相反,PATCH请求用于更新单个资源的部分,即仅应替换资源字段的特定子集。

PUT请求中,主要资源 ID 作为 URL 路径段传递,并且关联的资源将替换为有效负载中传递的表示形式(如果成功)。

UserDto对于有效负载,您可以提取另一个模型域类,其中包含除 ID 之外的所有字段。

据此,我建议您这样设计控制器:

@RestController
@RequestMapping("/api/{api}/users")
public class UserController {

  @PutMapping("/{id}")
  String update(@PathVariable String id, @RequestBody UpdateUserRequest request){
      service.update(id, request);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • tnx,我们希望避免将 `id` 转发到服务:) (4认同)
  • 从更新的角度来看,是的,这是有道理的。但从更一般的情况(对实体的任何非 CRUD 操作)来看,我认为将“id”作为“dto”的一部分更有意义 (4认同)