【问题标题】:how to convert from String to enum during BeanUtils.copyProperties in Spring Boot Rest API如何在 Spring Boot Rest API 中的 BeanUtils.copyProperties 期间从字符串转换为枚举
【发布时间】:2019-01-21 12:20:15
【问题描述】:

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

我在用户实体类中将 userStatus 值设为 null。

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

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

【问题讨论】:

    标签: java rest spring-boot enums dto


    【解决方案1】:

    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; } }

    它应该可以,但我也不是它的忠实粉丝......

    【讨论】:

      【解决方案2】:

      枚举不能为null,因为它们的下划线值为int,但您可以将enum 中的FIRST 值 设置为默认值。您还可以将 DTO 中的字段定义为 Enum 类型而不是 String。

      用户状态

      public enum UserStatus {
          NULL,
          ACTIVE,
          INACTIVE;
      
      }
      

      服务代码:

      userDto.setUserStatus(UserStatus.NULL);
      userDto.buildUser();
      

      或者如果你想设置这个覆盖 copyProperties 方法以在转换时忽略 userStatus 字段:

       public static void copyProperties(Object source, Object target,
                                         @Nullable Class<?> editable,
                                         @Nullable String... ignoreProperties); 
      

      【讨论】:

      • 如果我忽略该字段,它将如何转换为枚举值?
      猜你喜欢
      • 2014-01-17
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 2016-07-30
      • 1970-01-01
      • 2022-01-10
      • 2013-06-27
      相关资源
      最近更新 更多