java - Spring MVC PATCH方法: partial updates

标签 java json spring rest spring-mvc

我有一个项目,我正在使用 Spring MVC + Jackson 构建 REST 服务。假设我有以下 java 实体

public class MyEntity {
    private Integer id;
    private boolean aBoolean;
    private String aVeryBigString;
    //getter & setters
}

有时,我只想更新 boolean 值,我不认为发送带有大字符串的整个对象只是更新一个简单的 boolean 值是一个好主意。所以,我考虑过使用 PATCH HTTP 方法只发送需要更新的字段。因此,我在 Controller 中声明了以下方法:

@RequestMapping(method = RequestMethod.PATCH)
public void patch(@RequestBody MyVariable myVariable) {
    //calling a service to update the entity
}

问题是:我怎么知道哪些字段需要更新?例如,如果客户端只想更新 boolean 值,我将得到一个带有空“aVeryBigString”的对象。我怎么知道用户只想更新 boolean 值,但不想清空字符串?

我已经通过构建自定义 URL “解决”了这个问题。例如,以下 URL:POST/myentities/1/abolean/true 将映射到只允许更新 boolean 值的方法。此解决方案的问题在于它不符合 REST。我不想 100% 符合 REST,但我不喜欢提供自定义 URL 来更新每个字段(特别是考虑到当我想更新多个字段时它会导致问题)。

另一种解决方案是将“MyEntity”拆分为多个资源并仅更新这些资源,但我觉得这没有意义:“MyEntity”一个普通资源,它不是< strong>由其他资源组成。

那么,有没有一种优雅的方法来解决这个问题?

最佳答案

这可能很晚了,但是为了新手和遇到同样问题的人,让我分享一下我自己的解决方案。

在我过去的项目中,为了简单起见,我只是使用 native java Map。它将捕获所有新值,包括客户端显式设置为 null 的 null 值。此时,很容易确定哪些java属性需要设置为null,不像你使用与你的域模型一样的POJO,你将无法区分客户端设置了哪些字段为null和它们只是不包含在更新中,但默认情况下将为空。

另外,您必须要求http请求发送您要更新的记录的ID,并且不要将其包含在补丁数据结构中。我所做的是将 URL 中的 ID 设置为路径变量,将补丁数据设置为 PATCH 正文。然后使用 ID,您将首先通过域模型获取记录,然后使用 HashMap,您可以使用映射器服务或实用程序来修补相关领域模型的更改。

更新

您可以使用这种泛型代码为您的服务创建一个抽象父类(super class),您必须使用 Java 泛型。这只是可能实现的一部分,希望你能明白。另外最好使用映射器框架,如 Orika 或 Dozer。

public abstract class AbstractService<Entity extends BaseEntity, DTO extends BaseDto> {
    @Autowired
    private MapperService mapper;

    @Autowired
    private BaseRepo<Entity> repo;

    private Class<DTO> dtoClass;

    private Class<Entity> entityCLass;

    public AbstractService(){
       entityCLass = (Class<Entity>) SomeReflectionTool.getGenericParameter()[0];
       dtoClass = (Class<DTO>) SomeReflectionTool.getGenericParameter()[1];
    }

    public DTO patch(Long id, Map<String, Object> patchValues) {
        Entity entity = repo.get(id);
        DTO dto = mapper.map(entity, dtoClass);
        mapper.map(patchValues, dto);
        Entity updatedEntity = toEntity(dto);
        save(updatedEntity);
        return dto;
    }
}

关于java - Spring MVC PATCH方法: partial updates,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17860520/

相关文章:

javascript - Play2.2 Java - 防止 Javascript 模板转义

python - 从 JSON 文件到 Numpy 数组

java - 如果我的内部对象为空,Optional.ofNullable 似乎不起作用?

java - 计算字符串中数字出现的次数

java - Java中逆时针旋转图像90度

json - Play2 向 JsObject 添加新字段

java - 在java中将chartmouselistener()添加到jfreechart

java - QueryDSL SQL 与 JDBCTemplate 之间的性能测试

java - 使用 FetchType.EAGER 时发生 CascadeType.ALL 错误

java - Spring 框架: Byte Array is corrupted when received