Java 如何在Spring Boot Rest API中的BeanUtils.copyProperties期间从字符串转换为枚举

Java 如何在Spring Boot Rest API中的BeanUtils.copyProperties期间从字符串转换为枚举,java,rest,spring-boot,enums,dto,Java,Rest,Spring Boot,Enums,Dto,我必须将属性从dto复制到实体类。 我正在使用BeanUtils.copyProperties() 在请求正文中,我发送如下内容: { "userName":"test", "userStatus": "I", } DTO类: public class UserDto { private String userName; private String userStatus; public User buildUser() { User user = n

我必须将属性从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;

}
public enum UserStatus {
    NULL,
    ACTIVE,
    INACTIVE;

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

服务代码:

User user = userDto.buildUser();
userDto.setUserStatus(UserStatus.NULL);
userDto.buildUser();
我在用户实体类中将userStatus值设置为null

当我将UserDto.userStatus更改为枚举类型时,请求主体不接受空值


如何在BeanUtils.copyProperties()期间从字符串转换为枚举?

枚举不能为
null
,因为它们的下划线值为
int
,但您可以将
枚举中的第一个值设置为默认值。t您还可以将DTO中的字段定义为枚举类型而不是字符串

用户状态

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;

}
public enum UserStatus {
    NULL,
    ACTIVE,
    INACTIVE;

}
服务代码:

User user = userDto.buildUser();
userDto.setUserStatus(UserStatus.NULL);
userDto.buildUser();
或者,如果要在转换时将
copyProperties
方法的此重写设置为忽略
userStatus
字段:

 public static void copyProperties(Object source, Object target,
                                   @Nullable Class<?> editable,
                                   @Nullable String... ignoreProperties); 
publicstaticvoidcopyproperties(对象源、对象目标、,
@可编辑的空类,
@可为空的字符串…ignoreProperties);

Spring
BeanUtils
不是为此类定制而设计的。
您应该使用手动设置字段。
而MapStruct或打的是

作为保留
BeanUtils
和无显式setter调用的替代方法,您可以:

  • 定义枚举处理的工厂方法(在枚举类中注释为
    @JsonCreator
    的静态方法,例如:
@JsonCreator公共静态用户状态getValue(字符串名){
返回 Stream.of(UserStatus.values()) .findAny(s->s.name().equals(name)) .orElse(空); }

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

  • 将标志设置为忽略类的任何字段的未知值:
公共类UserDto{
@JsonIgnoreProperties(ignoreUnknown=true)
//...
}

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

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

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


它应该可以工作,但我也不是一个大风扇…

如果我忽略该字段,它将如何转换为枚举值?