【问题标题】:How to exclude value null from Put request when mapping to dto映射到dto时如何从Put请求中排除值null
【发布时间】:2019-08-04 08:24:25
【问题描述】:

我使用 RestController 更新数据到 db 但我有问题。当我更新值时,如果我的更新值为 null ,它总是将数据更新到 db 为 null。我不想要它。如果我的请求中有 1 个值为 null 的字段,我不想更新它。

下面是我的代码:

控制器:

休息控制器

@RequestMapping("/api/products")
@Api(value = "ProductControllerApi",produces = MediaType.APPLICATION_JSON_VALUE)

public class ProductController {

    @Autowired
    private ProductService productService;

    @PatchMapping("/{id}")
    public ResponseEntity<ProductResDto> updateProduct(@RequestBody ProductReqDto productReqDto, @PathVariable String id) {
        return ResponseEntity.ok(productService.updateProduct(product,id));
    }

ProductReqDto:

     public class ProductReqDto {

    private String name;
    private String type;
    private String category;
    private String description;
    private Double prince;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Double getPrince() {
        return prince;
    }

    public void setPrince(Double prince) {
        this.prince = prince;
    }
}

ProductResDto:

   public class ProductResDto {

    private String name;
    private String type;
    private String category;
    private Double prince;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Double getPrince() {
        return prince;
    }

    public void setPrince(Double prince) {
        this.prince = prince;
    }
}

MappingDto:

private ProductDto convertToProductDto(ProductReq product) {
    return modelMapper.map(product, ProductResDto.class);
}

我如何处理方法 convertToProductDto 只映射值不为空。因为如果,映射一个字段:example:product_name = null,它插入到db null。我想要如果字段 ProductReq 有值,它映射并保留数据库中的其他不同字段(如果不包含来自 ProductReq 的值,则不要将其设置为 null)。 示例:

**ReqProductDto.class**   
    private String name;
    private String type;
    private String category;
    private String description;
    private Double prince;

但如果用户只更新两个字段:

   private String name;
    private String type;

我想要 spring 更新字段 name 和字段 type 用户输入并在我的数据库中保留 category,description,prince。在我的情况下,如果用户更新两个字段:name 和字段 type,spring 更新它但 spring set category,description,prince 为 null在我的数据库中。我不想要它。 请帮助我,谢谢。

【问题讨论】:

  • 所以如果任何字段是null 你不想更新?或者更新有值的字段而不更新null 字段,你在找哪一个?
  • 我有更新问题。请帮忙
  • 您如何将这些数据保存到数据库中?你在用 spring-jpa 使用休眠吗?
  • 没有。我使用 TypeQuery 和写更新方法看起来像:objectdb.com/java/jpa/query/api .

标签: java spring spring-boot mapping dto


【解决方案1】:

您已将此标记为 spring-boot,所以我假设您可能正在使用控制器并验证它们的参数。如果是这种情况,那就去做吧

import javax.validation.constraints.NotNull;

public class ProductReqDto {

    @NotNull
    private String name;
    @NotNull
    private String type;
    @NotNull
    private String category;
    @NotNull
    private String description;
    @NotNull
    private Double prince;

    ...

}

并像这样为您的控制器使用@Valid

@PatchMapping("/{id}")
public ResponseEntity<ProductResDto> updateProduct(@RequestBody @Valid ProductReqDto productReqDto, @PathVariable String id) {
    return ResponseEntity.ok(productService.updateProduct(product,id));
}

然后您的对象将在实例化时得到验证。

【讨论】:

  • 我知道,但我想如果一个字段不需要为空,但用户忘记设置它,它不会映射到数据库中。值字段用户未设置保留值在数据库中。未设置为空
【解决方案2】:

你想要的主要用于PATCH映射。 在 PUT 映射中,对象的所有字段都需要覆盖,但在 PATCH 映射中,只需要覆盖提供的字段,其他字段不需要更改。

所以, 对于现有记录,

employee{ employeeId = "A2RTD", empName = "satish", "country": "India"}

而且,现在一个非强制字段 mobileNo 需要与国家一起更新

DTO 请求将包含除 id 以外的所有字段,但只有国家和手机号码不会为空

在这种情况下,我们可以使用 Spring 包中的 BeanUtils

import org.springframework.beans.BeanUtils;

public static Object getDtoMapping(Object source, Object destination) {
    BeanUtils.copyProperties(source, destination, getNullFieldNames(source));
    return destination;
}

public static String[] getNullFieldNames(Object source) {
    final BeanWrapper src = new BeanWrapperImpl(source);
    PropertyDescriptor[] pds = src.getPropertyDescriptors();

    Set<String> fieldNames = new HashSet<>();
    for (PropertyDescriptor pd : pds) {
        Object srcValue = src.getPropertyValue(pd.getName());
        if (srcValue == null)
            fieldNames.add(pd.getName());
    }

    String[] result = new String[fieldNames.size()];
    return fieldNames.toArray(result);
}

函数“getNullFieldNames”将返回值为 null 的字段名称。因此,根据 BeanUtils 中的第三个可选参数,这些字段将不会被映射

而且,你需要通过

// PATCH
EmployeeDao emp = findById(empCode);
emp = (EmployeeDao) getDtoMapping(empUpdateDto, emp);

这里,在 BeanUtil copyProperties 中,第三个参数是可选的。如果你给它用于 PATCH 映射,如果你不给它作为 PUT 映射。

因为,对于 PUT 映射,忽略 null 与不忽略相同。 您也可以在 POST、PUT 映射中使用相同的方法。

// POST MAPPING
EmployeeDao emp = (EmployeeDao) getDtoMapping(empCreateDto, new Employee());

【讨论】:

    猜你喜欢
    • 2020-04-08
    • 1970-01-01
    • 2015-07-29
    • 2014-11-18
    • 2019-11-12
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 2016-05-23
    相关资源
    最近更新 更多