我必须将属性从dto复制到实体类。
我正在使用BeanUtils.copyProperties()。

在请求正文中,我发送如下内容:

{
"userName":"test",
"userStatus": "I",
}


DTO类:

public class UserDto {
    private String userName;
    private String userStatus;

    public User buildUser() {
        User user = new User();
        BeanUtils.copyProperties(this, user);

        return user;
    }
}


实体类:

public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long userId;

    @Column(name = "user_name")
    private String userName;

    @Enumerated(EnumType.STRING)
    @Column(name = "user_status")
    private UserStatus userStatus;

}


注意:userStatus可以是表中的可为空字段。

服务代码:

User user = userDto.buildUser();


我在User实体类中将userStatus值设置为null。

当我将UserDto.userStatus更改为枚举类型时,则请求正文不接受空值。

在BeanUtils.copyProperties()期间如何将String转换为枚举?

最佳答案

Spring BeanUtils不适用于此类定制。
您应该手动设置该字段。
而MapStruct或Dozen则是。

作为保留BeanUtils的替代方法,您没有显式的setter调用:


定义用于枚举Jackson处理的工厂方法(在枚举类中带有@JsonCreator的静态方法,例如:


@JsonCreator public static UserStatus getValue(String name) {
return Stream.of(UserStatus.values()) .findAny(s -> s.name().equals(name)) .orElse(null);}


在大多数情况下,这是最好的解决方案,因为它从根本上解决了问题。


设置标志以忽略该类的任何字段的未知值:


public class UserDto { @JsonIgnoreProperties(ignoreUnknown = true) //...}

最快的解决方案,但我不太喜欢,因为它可能隐藏了其他一些序列化/反序列化问题。


添加代表空度的枚举值。您可以在DTO中定义枚举。
为了不将其存储在数据库中,应在实体本身中完成此枚举值到null的映射。
例如 :


public void setUserStatus(UserStatus userStatus){ if (userStatus != UserStatus.EMPTY){ this.userStatus = userStatus; }}

应该可以,但是我也不是一个大粉丝。

10-04 18:45