• Является ли объявление этой переменной бессмысленной или она улучшает читабельность кода?

    xez
    @xez Куратор тега Java
    TL Junior Roo
    С отдельной переменной, имхо, лучше
    Ответ написан
    Комментировать
  • Тестирование сервиса, можно ли создавать отдельный класс для хранения объектов тестирования или это плохая практика?

    xez
    @xez Куратор тега Java
    TL Junior Roo
    Можно и так.
    Я видел как некоторые ребята пишут DSL для тестов. (Типа: User user = ObjectFather.getDefaultUser().with ... .please())
    Ну а мне больше нравится тестовые данные хранить в виде джейсонов: джейсон легко хранить, легко просматривать, дегко преобразовывать в объект.
    Ответ написан
    2 комментария
  • Почему Spring Security отказывается пускать, несмотря на permitall()?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Я бы попробовал сделать следующее:
    1) изменить урл и попробовать заново. Например, /admin/**
    2) также попробуйте подебажить проект. Например, что возвращает:
    Role.ADMIN.getAuthority() и что ожидается на вход
    Ответ написан
    Комментировать
  • Стоит ли бросать кастомные ошибки, если этити не найдено в API?

    LaRN
    @LaRN
    Senior Developer
    Своей класс исключения имеет смысл бросать, если у вас для этого класса описан хэндленр, который сформиует правильный по бизнесу http ответ например.
    Вот тут описано как это делать
    https://spring.io/blog/2013/11/01/exception-handli...

    А строки не обязательно конкатенировать, можно использовать StringBuilder или String.format() например.
    Ответ написан
    3 комментария
  • Стоит ли бросать кастомные ошибки, если этити не найдено в API?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    Наверное, это зависит от того, как вы в команде договоритесь.
    Вы можете выбрасывать кастомные эксепшены, а далее ловить их в Controller или ControllerAdvice и отдавать соответствующее сообщение на клиент с кодом ошибки.
    Также можно обернуть entity в Optional и выбрасывать исключение orElseThrow() или возвращать другой объект (orElse()) или новый объект и т.д.

    Optional<Vote> voteOptional = voteRepository.findById(voteId);
            if(voteOptional.isEmpty()) {
                throw new ApiException("Vote with id " + id  + 
                        "is not in DB");
            }

    Можно же упростить:
    Vote vote = voteRepository.findById(voteId).orElseThrow(VoteNotFoundException::new);


    Но с другой стороны, если с фронта все правильно настроено, то таких ситуаций и не должно быть.

    не нужно надеяться на клиент. Например, человек может сам совершить запрос при помощи Postman и передать некорректное значение.
    Ответ написан
    8 комментариев
  • Где будет правильно расположить методы конвертации дто -> ентити и наоборот?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!

    Разместить прямо в дто в каждом.

    Почему бы вам не добавить методы конвертации в сервисный слой, где вы пишете вашу бизнес логику.
    Например, у вас есть entity User & dto - UserCreationDto. В сервисном слое UserService создайте 2 метода, которые конвертируют entity < -- > dto.
    Если вы используете встроенные возможности Spring (Converter<S, T>), то для каждого entity нужно создать свой класс. Что касается расположения пакетов, то есть разные практики. Например, в пакет user закинуть User, UserCreationDto, UserRepository, UserService, UserToDtoConverter и т.д.
    Если вы никак не кастомизируете процесс конвертации, то можно написать один базовый класс с использованием generics.
    Вот, простой пример для ModelMapper:
    @Service
    @RequiredArgsConstructor
    public class MapperService {
    
      private final ModelMapper modelMapper;
    
      /**
       * Note: outClass object must have default constructor with no arguments
       *
       * @param <D> type of result object.
       * @param <T> type of source object to map from.
       * @param entity entity that needs to be mapped.
       * @param outClass class of result object.
       * @return new object of <code>outClass</code> type.
       */
      public <D, T> D map(final T entity, Class<D> outClass) {
        return modelMapper.map(entity, outClass);
      }
    
      /**
       * Note: outClass object must have default constructor with no arguments
       *
       * @param entityList list of entities that needs to be mapped
       * @param outCLass class of result list element
       * @param <D> type of objects in result list
       * @param <T> type of entity in <code>entityList</code>
       * @return list of mapped object with <code><D></code> type.
       */
      public <D, T> List<D> mapAll(final Collection<T> entityList, Class<D> outCLass) {
        return entityList.stream().map(entity -> map(entity, outCLass)).collect(Collectors.toList());
      }
    
      /**
       * Maps {@code source} to {@code destination}.
       *
       * @param source object to map from
       * @param destination object to map to
       */
      public <S, D> D map(final S source, D destination) {
        modelMapper.map(source, destination);
        return destination;
      }
    }


    Создать отдельный класс DTOUtils и все туда скинуть ( но тогда там вперемешку будут методы конвертации всех классов )

    Не самая лучшая идея. Лучше так не делать. Вспоминаем про принцип единственной ответственности. (SOLID).

    Сделать пакет dtoutils и там создать много классов ( для каждого дто свой, они будут только хранить дто методы и все )

    Все зависит от вашего проекта. Иногда наличие одного пакета может быть оправданно, а иногда нет. Важно корректно сформировать структуру проекта.

    3 вариант выглядит как самый благоразумный, но создавать отдельный класс для одного метода это как-то не очень.

    Это вот, как раз тот случай, когда вы используете интерфейс Converter<S, T>
    https://docs.spring.io/spring-framework/docs/curre...
    Если не хотите создавать по одному классу на каждый dto, то можете глянуть на код указанный выше. Может, это будет для вас полезно
    Ответ написан
    4 комментария