Ответы пользователя по тегу Java
  • Spring boot - как происходит запуск?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Есть приложение, читающее файлы из файловой системы и загружающее в БД часть содержимого.

    Ну в данном случае для импорта БД нужно использовать sql скрипты и какую-нибудь либу. Например, flyway.

    Есть сервисные классы, в них ряд методов, но возвращаемые типы в методах повторяются.

    Если это необходимо, то можно использовать дженерики.

    Хотелось бы сделать без спринг шелла, без команд в мейне.

    По идее flyway (или например, liquibase) лучше подходят для этих целей.
    Ответ написан
    Комментировать
  • Правильно ли я называю тесты?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Вопрос не глупый. Ведь, от правильного нейминга зависит то, насколько хорошо ваш код будет читаемым.
    Вот, информация о конвенции нейминга тестов.
    https://dzone.com/articles/7-popular-unit-test-naming
    Ответ написан
    Комментировать
  • Как в слое DAO при помощи JDBC получить корректную сущность?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    В Hibernate при использовании аннотации ManyToMany создаются 3 таблицы. 2 таблицы для самих сущностей, где хранится информация и 1 таблица с маппингами, где хранятся id сущностей. В данном случае с вашими таблицами все в порядке.

    У возвращаемого автора должны быть проинициализированы поля books и genres. Там должны находится
    книги которые писал автор и жанры в которых он работал. В свою очередь у каждой книги должна быть
    информация в каком жанре она написана и какие у нее авторы. А жанр должен хранить список книг относящихся к нему
    и авторов работающих в данном жанре.


    При такой работе (при сериализации данных или при вызове метода toString) вы столкнетесь с рекурсией. Например, у автора есть список книг, у книг есть авторы и каждый раз будут вызваны методы, которые будут запрашивать то авторов, которые написали эту книгу, то книги, которые был написаны этим автором. Эти вопросы при работе с Jackson решаются при помощи аннотаций JsonManagedReference & JsonBackReference или JsonIgnore. Для lombok для исключения из toString можно использовать ToString.Ignore.

    Таким образом возвращая автора сервис слою мы должны загрузить кучу информации из базы данных, и это будет не один запрос, а очень много.

    Если мы говорим о hibernate (jpa), то там есть таккие параметры, как FetchType (EAGER & LAZY). Так вот, если LAZY, то информация из List будет загружена только при обращении к ней. В случае EAGER информация загружается при первом же обращении к сущности.
    https://thorben-janssen.com/entity-mappings-introd...

    Возможно, что эта ссылка будет полезна для вас:
    https://stackoverflow.com/questions/21956042/mappi...
    Ответ написан
  • Как получить доступ к owner?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Вот, гляньте на структуру pojo для вашего json
    Было сгенерировано на сайте - https://www.jsonschema2pojo.org/
    -----------------------------------com.example.Example.java-----------------------------------
    
    package com.example;
    
    import java.util.List;
    import javax.annotation.Generated;
    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    
    @Generated("jsonschema2pojo")
    public class Example {
    
    @SerializedName("total_count")
    @Expose
    public Long totalCount;
    @SerializedName("incomplete_results")
    @Expose
    public Boolean incompleteResults;
    @SerializedName("items")
    @Expose
    public List<Item> items = null;
    
    }
    -----------------------------------com.example.Item.java-----------------------------------
    
    package com.example;
    
    import javax.annotation.Generated;
    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    
    @Generated("jsonschema2pojo")
    public class Item {
    
    @SerializedName("id")
    @Expose
    public Long id;
    @SerializedName("node_id")
    @Expose
    public String nodeId;
    @SerializedName("name")
    @Expose
    public String name;
    @SerializedName("full_name")
    @Expose
    public String fullName;
    @SerializedName("private")
    @Expose
    public Boolean _private;
    @SerializedName("owner")
    @Expose
    public Owner owner;
    @SerializedName("html_url")
    @Expose
    public String htmlUrl;
    @SerializedName("description")
    @Expose
    public String description;
    @SerializedName("fork")
    @Expose
    public Boolean fork;
    
    }
    -----------------------------------com.example.Owner.java-----------------------------------
    
    package com.example;
    
    import javax.annotation.Generated;
    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    
    @Generated("jsonschema2pojo")
    public class Owner {
    
    @SerializedName("login")
    @Expose
    public String login;
    @SerializedName("id")
    @Expose
    public Long id;
    @SerializedName("node_id")
    @Expose
    public String nodeId;
    @SerializedName("avatar_url")
    @Expose
    public String avatarUrl;
    @SerializedName("gravatar_id")
    @Expose
    public String gravatarId;
    @SerializedName("url")
    @Expose
    public String url;
    @SerializedName("html_url")
    @Expose
    public String htmlUrl;
    @SerializedName("followers_url")
    @Expose
    public String followersUrl;
    @SerializedName("following_url")
    @Expose
    public String followingUrl;
    @SerializedName("gists_url")
    @Expose
    public String gistsUrl;
    @SerializedName("starred_url")
    @Expose
    public String starredUrl;
    @SerializedName("subscriptions_url")
    @Expose
    public String subscriptionsUrl;
    @SerializedName("organizations_url")
    @Expose
    public String organizationsUrl;
    @SerializedName("repos_url")
    @Expose
    public String reposUrl;
    @SerializedName("events_url")
    @Expose
    public String eventsUrl;
    @SerializedName("received_events_url")
    @Expose
    public String receivedEventsUrl;
    @SerializedName("type")
    @Expose
    public String type;
    @SerializedName("site_admin")
    @Expose
    public Boolean siteAdmin;
    
    }
    Ответ написан
    Комментировать
  • Какую аннотацию лучше всего использовать для ролей ( для Hibernate ) в Spring?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Я обычно делаю это иным образом.
    1) создаю enum UserRole, UserPrivilege
    2) создаю entity Role. При необходимости можно еще добавить сет из Privilege для каждой роли
    3) Далее каждый entity содержит роль или сет ролей.
    4) сущность User связываю с сущностью UserRole

    Вот, исходники:
    Сущность User
    @Entity
    @Data
    @Table(name = "users")
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode(callSuper = false)
    public class User {
    
      //...
    
      @JsonBackReference
      @ToString.Exclude
      @ManyToMany(fetch = FetchType.EAGER)
      @JoinTable(
          name = "users_roles",
          joinColumns = @JoinColumn(name = "user_id"),
          inverseJoinColumns = @JoinColumn(name = "role_id"))
      private Set<Role> roles;
    
    }


    Сущность Role
    @Entity
    @Data
    @EqualsAndHashCode(callSuper = false)
    @Table(name = "roles")
    public class Role implements GrantedAuthority {
    
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE)
      private Long roleId;
    
      @JsonBackReference
      @ToString.Exclude
      @ManyToMany(mappedBy = "roles")
      private Collection<User> users;
    
      @JsonBackReference
      @ToString.Exclude
      @ManyToMany
      @JoinTable(
          name = "roles_privileges",
          joinColumns = @JoinColumn(name = "role_id"),
          inverseJoinColumns = @JoinColumn(name = "privilege_id"))
      private Collection<Privilege> privileges;
    
      @Enumerated(EnumType.STRING)
      private UserRole name;
    
      public Role() {
        super();
      }
    
      public Role(UserRole name) {
        super();
        this.name = name;
      }
    
      @Override
      public String getAuthority() {
        return name.name();
      }
    }


    enum UserRole
    public enum UserRole {
      USER,
      ADMIN
    }


    сущность Privilege
    @Entity
    @Data
    @EqualsAndHashCode(callSuper = false)
    @Table(name = "privileges")
    public class Privilege {
    
      
    
      @Enumerated(EnumType.STRING)
      private UserPrivilege name;
    
      @JsonBackReference
      @ToString.Exclude
      @ManyToMany(mappedBy = "privileges")
      private Collection<Role> roles;
    
    
    }


    enum UserPrivilege
    public enum UserPrivilege {
      ADMIN_PRIVILEGE,
      READ_PRIVILEGE,
      WRITING_COMMENTS_PRIVILEGE
    }
    Ответ написан
    6 комментариев
  • При запуске проекта на эмуляторе получаю Execution failed for task ':app:compileDebugJavaWithJavac', как решить?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый вечер.
    Попробуйте для начала глянуть на ответы, которые были на разных ресурсах по данному вопросу.
    Например,
    https://github.com/gradle/gradle/issues/15538
    https://github.com/gradle/gradle/issues/16641
    Гугл
    Ответ написан
    Комментировать
  • Почему Spring Security отказывается пускать, несмотря на permitall()?

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

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Можно по-разному реализовать. Например, использовать стримы (как отметил коллега Dmitry Roo) или например, использовать метод repeat()

    Scanner scanner = new Scanner(System.in);
            System.out.println("Введите слово\n");
            String word = scanner.nextLine();
            String[] splittedWord = word.split("");
            for (String character : splittedWord) {
                System.out.print(character.repeat(3));
            }
    Ответ написан
    5 комментариев
  • Чьи объекты использовать: сервера или клиента?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Я сделал зависимость клиента от сервера, то есть удалил класс User из клиента и импортировал этот класс из серверного модуля.

    Можно создать модуль common и закинуть туда ваши общие классы.
    Я вообще делаю примрено следующим образом: создаю несколько модулей один из которых persistence, где располагаются сущности и репозитории, второй модуль common, где содержатся утильные классы и сервисные классы, а также модуль web (где хранятся контроллеры, мапперы, соответсвующие эксепшены и их обработчики, шаблоны и т.д.). Ну и дальше уже по необходимости... например, модуль api для rest. Также создаю отдельный модуль для flyway и хранения sql скриптов. Разумеется, что структура у вас может отличаться в зависимости от вашей задачи..
    Ответ написан
    Комментировать
  • Как изучать Spring? Где нормальная документация?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Подскажите как лучше изучать spring, какой современный стек?

    Пожалуй, все фреймворки изучаются на основе книг, документаций, а также туториалов. Спринг не является исключением.

    Туториалы: John Thompson - (Spring Guru)
    https://www.udemy.com/courses/search/?q=john+thomp...
    Есть чуть попроще Dan Vega - Learn Spring Boot
    https://www.udemy.com/course/spring-boot-intro/
    Также Наиль Алишев - Spring Framework
    https://www.youtube.com/watch?v=5ePo08sqcpk

    Что касается книг, то можно начать с Spring Boot in Action (Spring Boot в действии)

    Что касается документаций:
    https://docs.spring.io/spring-boot/docs/current/re...
    https://www.baeldung.com/

    Ну и у baeldang есть неплохие курсы по Spring
    https://www.baeldung.com/learn-spring-course
    Ответ написан
    Комментировать
  • Как полученный POST запрос с JSON телом, обработать и отдать ответ в виде XML?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    У вас должно быть 2 DTO.
    1 - для получения json из POST запроса.
    2 - для возврата xml в ответе.
    После обработки json вам нужен некий маппер (можно использовать интерфейс Converter<S,T>), который сконвертирует ваш Request в Response.
    Тут должно быть примерно так:
    @PostMapping(path = "/save", 
       produces = {"application/xml", "text/xml"}, consumes = 
                    MediaType.ALL_VALUE)
      public ResponseEntity<Response> pay(@RequestBody Request request){
        service.save(request);
    // тут конвертируем request в response
        return ResponseEntity.ok(response);
          }
       }


    Вот, примерная структура dto для xml response
    public class response { 
    	public int p_id;
    	public int status;
    	public String message;
    	public int id;
    	public Date dts;
    	public String text;
    }
    Ответ написан
    Комментировать
  • Написать программу редактирующую страницу в wordpress?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    Мне приходилось писать подобные приложения.
    Вам необходимо работать с Wordpress REST API.
    Есть Java клиент.
    Используйте эту либу:
    https://github.com/Afrozaar/wp-api-v2-client-java
    Также на ВП сайт установите этот плагин, чтобы можно было авторизовать сторонний клиент
    https://github.com/WP-API/Basic-Auth
    Если вам нужно редактировать метаданные на сайте ВП, то установите этот плагин на сайт
    https://github.com/Afrozaar/wp-api-v2-client-java-...
    Можете также глянуть на:
    https://github.com/Afrozaar/wp-api-v2-afrozaar-extras

    При необходимости вы можете использовать другой фреймворк:
    Apache Camel + Apache Camel WP Component
    https://camel.apache.org/
    https://camel.apache.org/components/3.4.x/wordpres...
    Ответ написан
    Комментировать
  • Будет ли курс и книги по Java 2019 года выпуска актуальны в 2021?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Я бы рекомендовал вместо книги Г. Шилдт "Руководство по Java для начинающих" прочитать книгу Г. Шилдт "Полное руководство по Java".

    Единственное что смущает, что и книга и курс выпущены в 2019 году.

    Год выпуска не имеет столь важного значения. Можно взять книгу хоть 2009 года. Важно, чтобы книга, которую вы прочитаете была написана про Java 8 или выше, так как начиная с этой версии было внесено много изменений в язык (Java Stream API и т.д.).

    Насколько актуальны они будут для начального погружения в Java?

    Для начинающих актуально все, что можно прочитать.

    Если есть что-то более свежее, можете посоветовать?

    Можете смело начать с книг Г. Шилдта. Есть еще одно пособие для начинающих - Java Head First. Но как по мне там слишком много воды...

    Что касается курсов на Udemy или youtube, coursera и т.д. из всех авторов мне нравится Наиль Алишев. Я видел его курсы по git & spring framework. Вроде у него есть 2 курса по java тоже на udemy. Сказать что-либо объективного по поводу вашего курса на Udemy не могу, ибо не знаю.
    Также есть зарубежные разработчики. Например, John Thompson, Tim Buchalka и др.
    Ответ написан
    1 комментарий
  • Как сделать свою библиотеку "популярной"?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    Тут вопрос больше не про Java, а скорее про популяризацию того или иного материала (будь то библиотека для Java или что-то другое).
    В таком случае можно рекомендовать вам написать статьи, обзоры и туториалы в таргетных сайтах. Для разработчиков хорошо подойдут такие сайты, как Хабр, Medium. Можно также закинуть видео на youtube с демо или туториалом вашей библиотеки. Конечно же материалы предоставить в двух языковых версиях - на английском и на русском.
    Также очень полезно бывает залить ее исходники (если это опенсора) на все гит репозитории (github, gitlab, bitbucket) и также максимально подробно написать README.md, чтобы люди могли без затруднений найти исходники вашей либы в просторах интернета.
    Ответ написан
    Комментировать
  • Как конвертировать валюты с расчетом по любому полю?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    Логика реализации примерно следующая:
    вам нужен некий event listener, который отслеживает изменения полей. Если было изменено одно из полей, то берем значение этого поля и получаем тип (валюту) данного поля. А далее уже отправляем запрос по АПИ и получаем соответствующие котировки.
    Ответ написан
  • Разные ДТО для создания/получения объектов VS один ДТО, но запретить сериализацию null?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Как по мне лучше создавать отдельный DTO на каждую нужду вместо того, чтобы скомпоновать все в один.
    Например, UserCreationDTO, UserRequestDTO, UserResponseDTO и т.д.
    Ответ написан
    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 комментария
  • Не могу найти что-то на что можно нажать. Как нажать на элемент?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Нажать можно на все что угодно, все зависит от того на что повешено событие (event).
    В данном случае событие висит на элементе div
    Вот, селектор div.card.mt-4.top-card
    O7JNhGv.png
    Ответ написан
    Комментировать
  • Как распространять программу java вместе с базой данных?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Можно использовать h2 БД. Его можно встраивать, а также сохранять в файловой системе. Также можно глянуть в сторону sqlite. Или же можно использовать postgres embedded.
    Для удобства работы с выбранной БД используйте ORM (hibernate, ormlite и др)
    Ответ написан
    Комментировать