Как преобразовать из String в enum во время BeanUtils.copyProperties в API Spring Boot Rest - PullRequest
0 голосов
/ 21 января 2019

Мне нужно скопировать свойства из 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 как ноль в классе сущности User.

Когда я изменил UserDto.userStatus на тип enum, тело запроса не принимает пустое значение.

Как мне преобразовать String в enum во время BeanUtils.copyProperties ()?

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Spring BeanUtils не предназначен для таких настроек.
Вы должны установить поле вручную с помощью.
Хотя MapStruct или дюжина есть.

В качестве альтернативы для сохранения BeanUtils и без явного вызова сеттера у вас есть:

  • определение фабричного метода для обработки перечисления Джексона (статический метод, аннотированный @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) //... }

Самое быстрое решение, но мне оно не очень нравится, так как оно может скрыть некоторые другие проблемы сериализации / десериализации.

  • добавление значения enum, представляющего пустоту. Вы могли бы так определить перечисление в DTO.
    Чтобы не сохранять его в базе данных, сопоставление этого значения перечисления с null должно выполняться в самой сущности.
    Например:

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

Это должно работать, но я не большой поклонник ...

0 голосов
/ 21 января 2019

Перечисления не могут быть null, потому что их значения подчеркивания int, но вы можете установить значение FIRST в enum в качестве значения по умолчанию. Вы также можете определить свое поле в DTO как тип Enum вместо String.

UserStatus

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); 
...