Как пропатчить Dto для Entity? - PullRequest
2 голосов
/ 18 февраля 2020

У меня есть контроллер, который принимает объект dto. Мне нужно изменить поля, присутствующие в объекте dto.

@PatchMapping(value = "/update/{uuid}")
    public ResponseEntity<UserDto> update(
            @RequestBody UserDto userDto,
            @PathVariable("uuid")UUID uuid) throws UserNotFoundException {           
        User updatedUser = userService.update(
                userMapper.userDtoToUser(userDto),
                uuid
        );           
        return .....
    }

Но userService может принимать только сущности. Мне нужно использовать маппер dto -> entity. Но у сущности не может быть пустых полей, которые входят в dto (допустим, вам нужно изменить только одно поле). Что делать в этой ситуации? Я знаю, что контроллер не должен содержать лог c

Ответы [ 3 ]

1 голос
/ 18 февраля 2020

Два возможных способа решения этой проблемы. Вам нужно либо изменить метод обслуживания, чтобы он принимал dto, а не сущность, либо создать класс @Component, который реализует Converter , переопределить метод convert и тут же внести необходимые изменения в поле @Autowire GenericConversionService в вашем контроллере и вызовите genericConversionService.convert(userDto, User.class);

Преобразователь должен выглядеть следующим образом:

import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

@Component
public class UserDtoToUser implements Converter<UserDto, User> {

    @Override
    public User convert(UserDto source) {
        User user = new User();
        // user.set ..... for all necessary fields
        return user;
    }

}

РЕДАКТИРОВАТЬ

Если вы хотите проверить достоверность полей, которые вы получаете, вы можете просто использовать следующие аннотации, чтобы убедиться, что ваши данные верны: @ NotBlank - это проверяет, является ли поле пустым или пустым строка, @ NotNull - это проверяет, является ли поле пустым, @ NotEmpty - это проверяет, является ли поле нулевым или пустой коллекцией. Важно помнить - вы должны добавить аннотацию @Valid перед объектом, который вы хотите проверить (примечание - в случае вложенных объектов вам также необходимо добавить его в поля вашего объекта), чтобы он выглядел следующим образом @RequestBody @Valid UserDto userDto,

А затем для dto это должно выглядеть примерно так:

import java.util.List;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

public class UserDto {
    @NotNull
    private Integer id;

    @NotBlank
    private String username;

    @NotBlank
    private String password;

    @NotEmpty
    private List<String> roles;
}

Измените поля на то, что есть в вашем dto, конечно. Также, если вам нужно сделать больше проверок, вы можете добавить ряд других аннотаций проверки.

0 голосов
/ 18 февраля 2020

Как вы говорите, контроллер не должен содержать логики c, поэтому для этой Spring есть интерфейс, интерфейс Validator

Есть плюсы и минусы для рассмотрения валидации в качестве бизнес-логики c, и Spring предлагает дизайн для проверки (и привязки данных), который не исключает ни один из них. В частности, валидация не должна быть привязана к веб-уровню, должна быть легко локализована и должна быть возможность подключить любой доступный валидатор. Учитывая вышесказанное, Spring разработал интерфейс Validator, который является базовым c и в высшей степени пригоден для использования на каждом уровне приложения.

Это то, что вам нужно сделать:

Spring имеет интерфейс Validator, который вы можете использовать для проверки объектов. Интерфейс Validator работает с использованием объекта Errors, поэтому при проверке валидаторы могут сообщать об ошибках валидации объекту Errors.

у нас есть DTO, к которому мы будем проверять поля:

public class Person {
    private String name;
    private int age;

    // the usual getters and setters...
}

Для выполнения проверок мы должны реализовать интерфейс Validator:

    public class PersonValidator implements Validator {

    /**
     * This Validator validates *just* Person instances
     */
    public boolean supports(Class clazz) {
        return Person.class.equals(clazz);
    }

    public void validate(Object obj, Errors e) {
        if (supports(obj.getClass())) {
            ValidationUtils.rejectIfEmpty(e, "name", "name.empty");
            Person p = (Person) obj;
            if (p.getAge() < 0) {
                e.rejectValue("age", "negativevalue");
            } else if (p.getAge() > 110) {
                e.rejectValue("age", "too.darn.old");
            }
        }
    }
}

Если DTO проходит все проверки, вы можете сопоставить DTO с объектом Entity

Более подробную информацию можно найти здесь Пружинный валидатор

0 голосов
/ 18 февраля 2020

Вы можете использовать отражение, чтобы проверить нулевые свойства, и BeanUtils для копирования.

В Spring это будет способ проверки пустых свойств

* 1006. *

А потом для копирования

User updatedUser = new User();
BeanUtils.copyProperties(userDto, updatedUser, getNullPropertyNames(userDto));
...