我必须将属性从 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() 期间从字符串转换为枚举?
最佳答案
Spring BeanUtils
不适合此类定制。
您应该手动设置该字段。
而 MapStruct 或 Dozen 则是。
作为保留 BeanUtils
的替代方案并且没有显式的 setter 调用:
- 为枚举 Jackson 处理定义一个工厂方法(在枚举类中注释为
@JsonCreator
的静态方法,例如:
@JsonCreator public static UserStatus getValue(String name) {<br/>
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;
}
}
它应该有效,但我也不是它的忠实粉丝......
关于java - 如何在 Spring Boot Rest API 中的 BeanUtils.copyProperties 期间从 String 转换为 enum,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54289859/