简体   繁体   English

Java - RestAPI - 补丁无法有效工作

[英]Java - RestAPI - Patch not working efficiently

I've a small problem with my method using protocol PATCH in my RestController, I'm creating an object Warehouse.我在 RestController 中使用协议 PATCH 的方法有一个小问题,我正在创建一个对象仓库。

1st I'm creating it via POST: 1st 我通过 POST 创建它:

{
    "location" : "Paris",
    "maxCapacity" : "200"
}

Result:结果:

[
    {
        "id": 1,
        "location": "Paris",
        "currentCapacity": 0,
        "maxCapacity": 200,
        "cargosList": [],
        "status": "EMPTY"
    }
]

When for example, PATCHing only field location:例如,仅修补字段位置时:

{
    "location" : "New York"
}

And when reading with GET:使用 GET 阅读时:

[
    {
        "id": 1,
        "location": "New York",
        "currentCapacity": 0,
        "maxCapacity": null,
        "cargosList": [],
        "status": "EMPTY"
    }
]

Why the field maxCapacity have been changed to null although my PATCH request was only on field location?尽管我的 PATCH 请求仅在字段位置上,但为什么字段 maxCapacity 已更改为 null?

My Entity:我的实体:

package net.erickcaron.warehouseapplicationapi.models;

import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.*;

import javax.persistence.*;
import java.util.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor

@Entity(name = "warehouses")
public class Warehouse {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String location;
    private Integer currentCapacity = 0;
    private Integer maxCapacity;

    @OneToMany
    @JsonManagedReference
    private List<Cargo> cargosList = new ArrayList<>();

    @Enumerated(value = EnumType.STRING)
    private WarehouseStatus status = WarehouseStatus.EMPTY;


}

My RestController:我的休息控制器:

package net.erickcaron.warehouseapplicationapi.rest;

import net.erickcaron.warehouseapplicationapi.models.Warehouse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import net.erickcaron.warehouseapplicationapi.services.WarehouseService;

import javax.transaction.Transactional;
import java.util.List;

@Transactional
@RestController
@RequestMapping("/warehouses")
public class WarehouseRestController {

    @Autowired
    private WarehouseService warehouseService;

    @PostMapping
    public Integer create(@RequestBody Warehouse warehouse){
        return warehouseService.create(warehouse);
    }

    @GetMapping("/{id}")
    public Warehouse findById(@PathVariable Integer id){
        return warehouseService.findById(id);
    }

    @GetMapping
    public List<Warehouse> findAll(){
        return warehouseService.findAll();
    }

    @PatchMapping("/{id}") //TODO not working!
    public void partialUpdate(@PathVariable Integer id, @RequestBody Warehouse warehouse){
        warehouseService.partialUpdate(id, warehouse);
    }

    @DeleteMapping("/{id}")
    public void deleteById(@PathVariable Integer id){
        warehouseService.deleteById(id);
    }

    @PatchMapping("/{warehouseId}/cargos/{cargoId}")
    public void addCargoToWarehouse(@PathVariable Integer warehouseId, @PathVariable Integer cargoId){
        warehouseService.addCargoToWarehouse(warehouseId, cargoId);
    }






}

Thanks for any help, Regards, Erick感谢您的帮助,问候,埃里克

Use a mapper to update your Entity and then persist it again.使用mapper更新您的实体,然后再次保留它。 I can more than recommend MapStruct !我不仅可以推荐MapStruct

You can create a Mapper this way:您可以通过以下方式创建Mapper

@Mapper
public interface WarehouseMapper {
    
    // Ignore null Values
    @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
    void updateWarehouse(Warehouse updatedWarehouse, @MappingTarget Warehouse oldWarehouse);
}

Then you can get your mapper in the partialUpdate() function and use it this way:然后你可以在partialUpdate()函数中获取你的映射器并以这种方式使用它:

public void partialUpdate(Integer id, Warehouse updatedWarehouse) 
{ 
    Warehouse oldWarehouse = findById(id); 
    
    WarehouseMapper mapperInstance = Mappers.getMapper( WarehouseMapper.class );

    mapperInstance.updateWarehouse(updatedWarehouse, oldWarehouse); // Maps the NON NULL fields of updatedWarehouse to oldWarehouse fields
    
    warehouseRepository.save(oldWarehouse); 
}

OR或者

Do the mapping yourself and do not use any external dependencies:自己做映射,不要使用任何外部依赖:

public void partialUpdate(Integer id, Warehouse updatedWarehouse) 
{ 
    Warehouse oldWarehouse = findById(id); 
    
    if(updatedWarehouse.getLocation() != null)
    {
        oldWarehouse.setLocation(updatedWarehouse.getLocation());
    }
    
    // ... And so on for each field
    
    warehouseRepository.save(oldWarehouse); 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM