Ответы пользователя по тегу Java
  • Как сформировать структуру данных и вернуть на клиент?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Скажите пожалуйста, правильно ли я понимаю, что у вас есть таблица с данными, а также сами сущности (entity) и вы хотите вернуть результат полученный из БД на клиент?
    Т.е. меня интересует следующее: db first or code first?
    Если у вас code first, то значит сущности у вас имеются и вам необходимо создать доп. классы (DTO). Далее полученные данные из БД замаппить в DTO.
    Для маппинга (после того, как будут созданы DTO) можно использовать доп. либы: ModelMapper, MapStruct или же интерфейс Converter<S,T>
    Если хотите создать dto на основе имеющегос у вас json файла, то можно воспользоваться онлайн-сервисом или представляемой ими либой.
    Сервис - https://www.jsonschema2pojo.org/
    Кстати, вы уверены, что у вас в вопросе указаны данные в json?
    Вот, json:
    {
        "id": 1,
        "numberOperation": "010",
        "nameOperation": "Токарная",
        "workshop": 6465,
        "area": 7,
        "OO": true,
        "OTK": false,
        "PZ": true,
        "KPS": true,
        "transition": [
            {
                "id": 1,
                "nameTransition": "Закрепить деталь",
                "executor": [
                {
                    "id": 1,
                    "nameExecutor": "4784",
                    "tsht": "4",
                    "tpz": "9",
                    "test": "7",
                    "tshtCalculated": "",
                    "tpzCalculated": "",
                    "testCalculated": "",
                    "kvr": "973"
                }, ]
            },
    
        ]
    }

    И вот dto построенные на основе вышеуказанного json (обратите внимание, что код скорее всего необходимо подправить под ваши нужды)
    DTOs
    -----------------------------------com.example.Example.java-----------------------------------
    
    package com.example;
    
    import java.util.List;
    import javax.annotation.Generated;
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.annotation.JsonProperty;
    import com.fasterxml.jackson.annotation.JsonPropertyOrder;
    
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonPropertyOrder({
    "id",
    "numberOperation",
    "nameOperation",
    "workshop",
    "area",
    "OO",
    "OTK",
    "PZ",
    "KPS",
    "transition"
    })
    @Generated("jsonschema2pojo")
    public class Example {
    
    @JsonProperty("id")
    public Long id;
    @JsonProperty("numberOperation")
    public String numberOperation;
    @JsonProperty("nameOperation")
    public String nameOperation;
    @JsonProperty("workshop")
    public Long workshop;
    @JsonProperty("area")
    public Long area;
    @JsonProperty("OO")
    public Boolean oo;
    @JsonProperty("OTK")
    public Boolean otk;
    @JsonProperty("PZ")
    public Boolean pz;
    @JsonProperty("KPS")
    public Boolean kps;
    @JsonProperty("transition")
    public List<Transition> transition = null;
    
    }
    -----------------------------------com.example.Executor.java-----------------------------------
    
    package com.example;
    
    import javax.annotation.Generated;
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.annotation.JsonProperty;
    import com.fasterxml.jackson.annotation.JsonPropertyOrder;
    
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonPropertyOrder({
    "id",
    "nameExecutor",
    "tsht",
    "tpz",
    "test",
    "tshtCalculated",
    "tpzCalculated",
    "testCalculated",
    "kvr"
    })
    @Generated("jsonschema2pojo")
    public class Executor {
    
    @JsonProperty("id")
    public Long id;
    @JsonProperty("nameExecutor")
    public String nameExecutor;
    @JsonProperty("tsht")
    public Long tsht;
    @JsonProperty("tpz")
    public Long tpz;
    @JsonProperty("test")
    public Long test;
    @JsonProperty("tshtCalculated")
    public String tshtCalculated;
    @JsonProperty("tpzCalculated")
    public String tpzCalculated;
    @JsonProperty("testCalculated")
    public String testCalculated;
    @JsonProperty("kvr")
    public Long kvr;
    
    }
    -----------------------------------com.example.Transition.java-----------------------------------
    
    package com.example;
    
    import java.util.List;
    import javax.annotation.Generated;
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.annotation.JsonProperty;
    import com.fasterxml.jackson.annotation.JsonPropertyOrder;
    
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonPropertyOrder({
    "id",
    "nameTransition",
    "executor"
    })
    @Generated("jsonschema2pojo")
    public class Transition {
    
    @JsonProperty("id")
    public Long id;
    @JsonProperty("nameTransition")
    public String nameTransition;
    @JsonProperty("executor")
    public List<Executor> executor = null;
    
    }
    Ответ написан
    Комментировать
  • Можно ли как-то заранее внести данные в базу данных SQLite?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Разумеется можно.
    Вы можете создать некий sql файл и записать туда ваши запросы. А при запуске приложения импортировать их.
    Вот, похожие вопросы:
    https://stackoverflow.com/questions/47466913/sqlit...
    https://stackoverflow.com/questions/22890693/impor...
    Ответ написан
    Комментировать
  • Как разместить несколько телеграм ботов на сервере?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Можно докер поднять, чтобы вообще приложения не пересекались.
    + прописать необходимые записи для доменов
    Ответ написан
    Комментировать
  • Цикл for с вводом в консоль исполняется дважды, дебаг не производится?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    Рекомендую использовать Intellij IDEA Community Edition или Eclipse, хотя это не имеет отношения к проблеме.
    Что касается вашего вопроса, то символ 'Enter' тоже символ. Отсюда и 2 прохода
    Попробуйте:
    public static void main(String[] args)  {
        
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
          char symbol = scanner.next().charAt(0);
          if (symbol == 'S') {
            System.exit(-1);
          }
        }
    
      }
    Ответ написан
    1 комментарий
  • Как объединить 2 ArrayList в 1 по совпадающему значению (id)?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    Одно из возможных решений:
    - создайте Map<Long, Product>
    Long - id продукта
    - Добавьте элементы первого List'а в Map.
    - Итерируйте по второму List'у. Внутри цикла получите товар из Map по идентификатору объекта из второго List'a.
    - При помощи сеттеров назначьте значения.
    - Если товара с таким ID нет, то добавьте в Map

    Вот, похожий вопрос - https://stackoverflow.com/questions/12670756/join-...
    Ответ написан
    Комментировать
  • Разумно ли использовать DependencyInjection в JavaFX?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Да, разумно.
    Я даже скажу так, есть готовая либа на Spring со всеми возможностями спринга для JavaFX.
    https://habr.com/ru/post/478402/
    сама либа - https://github.com/rgielen/javafx-weaver
    Ответ написан
    1 комментарий
  • Как переименовать java в jar?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Думаю, что вам необходимо начать с изучения азов.
    jar - это java архив.
    java - это расширение файла до компиляции
    class - это расширение файла после компиляции (где хранится байт-код)

    Error: Could not find or load main class jdk Caused by: java.lang.ClassNotFoundException: jdk.

    Класс jdk не найден. Выложите исходный код, чтобы можно было понять в чем проблема. Надеюсь, что вы не забыли добавить main метод?
    Также вам нужен файл MANIFEST.mf куда нужно прописать Main-Class: jdk
    И еще один нюанс, если у вас много зависимостей, то возможно понадобится сделать fat jar (jar with dependencies)
    https://stackoverflow.com/questions/16222748/build...
    Ответ написан
    Комментировать
  • Как дозаполнить корректно поля для Entity при конвертации из DTO?

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

    Итак, насколько я вас понял, то вы хотите обновить существующую запись на основе данных, которые прибежали из контроллера в виде DTO.

    Во-первых, в данном случае стоит использовать PutMapping (full updates) или PatchMapping (partial updates)
    Читаем подробно тут:
    https://www.baeldung.com/http-put-patch-difference...

    Во-вторых, после того, как вы получили DTO вам необходимо его замаппить в Entity и обновить в БД. Однако, могут быть поля, которые не были заполнены в DTO и вы не хотите, чтобы они были применены, как null, так?

    Далее конвертирую в entity, но откуда мне взять значения тех полей, которых не было в запросе?

    Вам не нужно дозаполнять поля сконвертированного entity. Вам необходимо:
    1) найти этот entity по идентификатору.
    2) Если не хотите, чтобы null поля были применены к сущности, то при маппинге (см. ниже) сделать null check и если поле DTO null, то не сеттить его к сущности.
    3) сохранить сущность.

    Что касается маппинга:
    1) Вы можете использовать интерфейс Converter<S, T>. И для каждого из полей сделать проверку типа (псевдокод):
    if (fieldValue != null) { entity.setField(fieldValue); }

    2) Если вы используете какую-либо библиотеку для маппинга (modelMapper, MapStruct и др.), то используйте возможности либы. Например, для modelMapper:
    modelMapper.getConfiguration().setPropertyCondition(Conditions.isNotNull());

    https://stackoverflow.com/questions/45451025/how-t...

    Также прокомментирую ваши комментарии из другого ответа:
    вот мне интересно, как решается этот вопрос. Разве это нормально, что на каждый пришедший запрос к сервису приходится ходить к базе данных? И это без учета логики!

    Можно настроить кеширование и тогда, обращения к БД не будет.


    Это базовая ситуация, с которой сталкивается каждый. Допустим у меня entity Person с атрибутом даты рождения, которую я не хочу отображать в PersonDto. Когда пользователь пришлем мне PersonDto по API для, допустим, операции обновления, то как мне при конвертации в entity вернуть эту дату рождения, чтобы я мог сохранить новую сущность?

    Обратите внимание на то, что может быть несколько DTO.
    Например,
    PersonCreationRequest - dto, которое заполняется из фронта при создании юзера
    PersonCreationResponse - dto, которое заполняется из бекенда после создания юзера
    PersonUpdatingRequest - dto, которое заполняется из фронта при обновлении юзера
    PersonUpdatingResponse - dto, которое заполняется из бекенда после обновления юзера
    PersonDto - общее dto, которое заполняется из бекенда для других нужд.
    Могут быть и другие DTO...
    Соответственно, ответ на ваш вопрос - используйте разные DTO.

    Не знаю насколько точно смог ответить на ваш вопрос.
    Ответ написан
    1 комментарий
  • Практические задания в Java, хороший и понятный материал по ООП?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    https://www.hackerrank.com/domains/java
    https://app.codility.com/programmers/
    https://codingbat.com/java
    Гуглим - Java exercises или java oop exercises.
    Ну и ранее были заданы подобные вопросы в сервисе и получены ответы. Можете воспользоваться поиском
    Ответ написан
    Комментировать
  • Как спроектировать API, чтобы избежать ошибку 504 Gate away?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Проблема в том что, Из-за больших обращений в сторонний API, программа работает слишком долго(5-7 минут) при запуске на прод получаю 504 Gate away.

    Посмотрите в сторону WebFlux. В частности, можно использовать Flux<>

    При каждом итерации цикла используя WebClient стучится с параметром в сторонний API с БД и получает некие данные обратно.

    Есть ли возможность доработать сторонний API? Т.е. принадлежит ли он вам? Если да, то можете добавить доп. контроллер, который позволит массово обрабатывать запросы, тем самым уменьшив кол-во запросов с n до 1.
    Ответ написан
    Комментировать
  • Как обьеденить слова в колекции?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый вечер.
    1) У вас есть проблема тут:
    public String translate(String en) {
    
            for (Map.Entry<String, String> d : dictionary.entrySet())
                System.out.print(d.getValue() + " ");
            return en;
        }

    Вам нужно в метод передать слово на англ. языке, а вернуть слово на русском. А вы передаете и возвращаете англ. слово
    Add a new method translate(String en) which take some string in English, and returns
    its translation in Russian as the value of the type String.


    2) Это по идее, даже лишнее. В задании сказано, что пополнять словарь вы будете при помощи метода addNewWord
    public MyTranslator(HashMap<String, String> dictionary) {
            this.dictionary = dictionary;
        }


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

    Вам нужно используя метод get ввести ключ (слово на англ) и получить перевод ().
    Например,
    public String translate(String en) {
    return this.dictionary.get(en);
        }

    P.S. Тут коллега Dmitry Roo прав. Надо в метод translate получить строку, разбить ее на части, достать переводы с собрать в коллекцию. Я тут ошибся.

    4)
    Add code to read string from console and pass it into translate method. Print result to
    console.

    Создайте метод, который поможет прочитать и добавить слова в словарь из консоли. Смотрите в сторону Scanner, System.in
    Ответ написан
    Комментировать
  • Spring как отправить JSON строку?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    А вы js код откуда-то скопировали или как?
    1) Сама идея возврата json из контроллера в таком виде - не очень. Вам необходимо вернуть dto. А jackson уже сам сериализует в json
    @GetMapping("/json")
      public String getJSON2() {
        return "{ \"id\": 10, \"name\": \"Clementina DuBuque\", \"username\": \"Moriah.Stanton\","
            + " \"email\": \"Rey.Padberg@karina.biz\", "
            + "\"address\": { \"street\": \"Kattie Turnpike\", "
            + "\"suite\": \"Suite 198\", \"city\": \"Lebsackbury\", "
            + "\"zipcode\": \"31428-2261\", \"geo\": { \"lat\": "
            + "\"-38.2386\", \"lng\": \"57.2232\" } }";
      }


    2) Как отметил коллега Dmitry Roo у вас то, что происходит в браузере и то что происходит в js коде - это разные вещи.
    Вот, смотрите:
    В коде ниже вы совершаете GET запрос на /api/json.
    Во-первых, непонятно, что это: data: { command: "GetDriverInfo" },, а главное зачем и как она должна быть обработана контроллером.
    Во-вторых, непонятно какой параметр вы хотите получить:
    console.log(response.driverVer);, если такого параметра driveVer у вас нет в json.
    Ответ написан
    Комментировать
  • Зачем придумали clone(), если можно использовать конструктор копирования?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Думаю, тут дали полный и развернутый ответ на ваш вопрос:
    https://stackoverflow.com/questions/2427883/clone-...
    Ответ написан
    Комментировать
  • Как из вложенных объектов в классе сделать одну таблицу?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Ответ - никак.
    Как вы сами сказали, это объекты. А значит, их значения будут хранится в других таблицах. А этот объект при помощи foreign key будет ссылаться на вложенный объект.

    Есть правда, следующий вариант (если он вам подойдет):
    Если объект может быть встроенным, то вы можете вместо сущности использовать аннотации @Embeddable & @Embedded
    https://www.baeldung.com/jpa-embedded-embeddable
    Т.е. по факту колонки встраиваемого объекта будут добавлены к основной сущности

    P.S. есть еще один вариант реализации вашей задумки. Возможно, что не самый лучший.
    В общем, если вы используете БД postgres, то объект можно хранить в формате jsonb.
    Из коробки решения нет, но можно подключить доп. либу.
    Вот, похожий вопрос:
    https://stackoverflow.com/questions/51276703/how-t...

    Зависимость:
    <dependency>
        <groupId>com.vladmihalcea</groupId>
        <artifactId>hibernate-types-52</artifactId>
        <version>2.2.2</version>
    </dependency>


    @Type(type = "jsonb")
        @Column(columnDefinition = "jsonb")
        private List<Child> children;


    На мой взгляд, лучше не заморачиваться так. Имхо, правильнее создавать отдельные таблицы.
    Ответ написан
    1 комментарий
  • Джава ссылается на удаленный класс при компиляции?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    В общем, ответ на вопрос - имеется ошибка в коде: метод main быть статичным
    Ответ написан
    Комментировать
  • Servlets, где должна быть конвертация в DTO?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Конвертация может быть на разном уровне. Обычно, это на уровне сервиса или контроллера.
    https://www.baeldung.com/entity-to-and-from-dto-fo...
    Ответ написан
    Комментировать
  • Может ли Service иметь репозитории других классов?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Могу ли я прямо обратиться к репозиторию Entity A из Service B?

    Да, можно. Другой вопрос - хорошо ли.

    Или мне надо это делать вот так Service B -> Service A -> Repository A?

    Я предпочитаю этот способ.
    Причина следующая:
    Вот, представьте, что на сервисном уровне вы получаете Optional<T> из репозитория и в случае, если объект не найден, то на сервисном уровне выбрасываете исключение orElseThrow(). Ну а далее ExceptionHandler ловит исключение и отдает соответствующий код ошибки и сообщение на фронт.
    Если вы решите из сервиса А обратиться в репозиторий Б, то по факту вам нужно заново получить объект и выбросить исключение в случае, если он не найден, а это уже дублирование кода...
    Псевдокод:
    ServiceA {
    @Autowired
    RepoB repoB;
    @Autowired
    ServiceB serviceB;
    
    // 1 вариант
    List<Job> doSomeJob1(String email){
    User user =  repoB.findUserByEmail(email).orElseThrow(UserNotFoundException::new);
    return user.getJobs();
    }
    
    // 2 вариант
    List<Job> doSomeJob2(String email) {
    User user = serviceB.getUserByEmail(email);
    return user.getJobs();
    }
    
    RepoB {
    Optional<User> findUserByEmail(String email);
    }
    
    ServiceB {
    @Autowired
    RepoB repoB;
    
    User getUserByEmail(String email){
    return repoB.findUserByEmail(email).orElseThrow(UserNotFoundException::new);
    }
    
    }


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

    Проблема в том, что у меня все сервисы DTOшки, а для работы Service B нужны нормальные объекты, что делать в таком случае? Неужели создавать отдельные точно такие же методы просто без конверта в дто?

    Я это обычно, делаю по другому. Я возвращаю объекты из сервисов. А если мне нужно DTO, то есть отдельный сервис MapperService, который принимимает дженерик и возвращает соответствующие DTO.
    Ответ написан
    4 комментария
  • Нормально ли кидать эксепшены в Spring boot web app?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый вечер.
    Да, нормально.
    Само исключение (лог) не нужно отдавать на фронт.
    На фронт отдайте код http ошибки (4хх) и какое-нибудь кастомное сообщение: "Недостаточно средств".
    Посмотрите в сторону ExceptionHandler.
    Ответ написан
    Комментировать