干净的代码在Spring @PatchMapping中做域类的部分补丁?

时间:2018-12-10 07:03:36

标签: java spring spring-mvc spring-boot

在Spring中,我编写如下代码来处理PATCH请求:

@PatchMapping(path="/{orderId}", consumes="application/json")
public Order patchOrder(@PathVariable("orderId") Long orderId, @RequestBody Order patch) {
    Order order = repo.findById(orderId).get();
    if (patch.getDeliveryName() != null) {
        order.setDeliveryName(patch.getDeliveryName());
    }
    if (patch.getDeliveryStreet() != null) {
        order.setDeliveryStreet(patch.getDeliveryStreet());
    }
    if (patch.getDeliveryCity() != null) {
        order.setDeliveryCity(patch.getDeliveryCity());
    }
    //...
    //Check all fields in Order class.
    return repo.save(order);
}

显然,这里至少有两个缺点:

  1. 由于很多空检查,代码不干净。
  2. 即使将空检查抽象为一个函数,当我们更改Order类的定义时,仍然存在问题。也就是说,在Order类中删除字段或添加新字段时,也必须重写这段代码。

我知道我可以在客户端执行一些空检查,例如仅发送非空字段来执行PATCH,但是我想知道是否有一种优雅的方法吗?像对象映射还是其他方式?

3 个答案:

答案 0 :(得分:1)

首先要注意的是不要像下面那样检查null:

if (patch.getDeliveryName() != null) {
    order.setDeliveryName(patch.getDeliveryName());
}

您可以将其设置为一行:

order.setDeliveryName(StringUtils.isEmpty(patch.getDeliveryName()) ? "" : patch.getDeliveryName());

还使用spring提供的方法检查null和Empty值。

对于点“ b” ,您可以使用以下代码:

BeanUtils.copyProperties(bean2, bean1);

在pom.xml中添加以下依赖项

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.3</version>
</dependency>

答案 1 :(得分:0)

您可以使用Optional字段定义新的参数类型,例如OrderPatch。 (Spring为您映射到Optional)。在patchOrder()方法主体中,可以将Optional.orElse()与现有订单的值一起用作默认值,而无需使用if语句。

答案 2 :(得分:0)

在设置器中传递nullchecker:

  Order order = repo.findById(orderId).get();
  order.setByPatch(patch)

在类Order内

  public void setByPatch(Patch patch){
    this.setDeliveryName(patch.getDeliveryName());
    this.setDeliveryStreet(patch.getDeliveryStreet());
    this.setDeliveryCity(patch.getDeliveryCity());
  }

然后向设置器添加NullCheck ...

=========================================== 或者您可以参考: https://docs.spring.io/spring/docs/4.1.x/spring-framework-reference/html/validation.html

并在@RequestBody @Validated Order订单中向订单添加@Valid。 然后设置@ NotNull,@ NotBlank