Задать вопрос
  • Как к entity присоединить список других entity и потом работать с ними и со списком?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    Во-первых, на основании ваших слов:
    Есть сертификат(Certificate), у него может быть много тегов (Tag).
    Предполагается что в таблице тегов может быть куча дубликатов по имени, т.е. 3 сертификата могут иметь один и тот же тег "Java" ну или как-то так.

    Могу предположить, что связь OneToMany & ManyToOne не очень подходит.
    Вот, смотрите: один сертификат может иметь несколько тегов, но при этом один тег может относится к разным сертификатам. Тут явно связь ManyToMany.
    https://vladmihalcea.com/the-best-way-to-use-the-m...
    https://www.baeldung.com/jpa-many-to-many
    Соответственно, получится, что со стороны Certificate вы сможете получить список его тегов, а со тороны тега, можете получить список сертификатов, к которым он принадлежит.
    А то у вас получается, что и со стороны тега и сертификата OneToMany связь, но при этом с обеих сторон используется List
    При использовании ManyToMany будет создана новая таблица вида certificate_id | tag_id, где вы сможете хранить данные. И соответственно,
    Как к entity присоединить список других entity и потом работать с ними и со списком?

    Этот вопрос устранится само собой
    Ответ написан
    7 комментариев
  • Как выбросить IllegalArgumentException, если значение slot некорректно?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Условно говоря, вам нужно проверить не является ли переданное методу shotWithWeapon() значение slot меньше 0. Используйте конструкцию if. Дальше было бы неплохо узнать, каким типом данных является Slot. Например, если это массив, то нужно проверить входит ли переданное значение в массив значений. Ну а дальше внутри конструкции

    public void shotWithWeapon(int slot)  {
    if (slot < 0 || другие условия) {
    throw new IllegalArgumentException();
    }
            //TODO проверить на выход за границы
            // Проверить на выход за границы
            // Выбросить IllegalArgumentException, если значение slot некорректно
    
            Weapon weapon = weaponSlots[slot];
            weapon.shot();
        }
    Ответ написан
    Комментировать
  • Куда вставлять код формы?

    azerphoenix
    @azerphoenix
    Java Software Engineer
    Здравствуйте! Было бы нелпохо уточнить. Что является формой? Это form?
    Или это код размещения баннера (некий блок, типа div) или вообще некий iframe?
    А добавить блок на сайт можно по-разному. Например, использовать виджет html и вставить свой код туда.
    Или есть используете визуальный редактор Visual Composer (то в нем есть виджет html). Возможно, подобные виджеты есть и в других редакторах.
    Ну или добавить на уровне кода (шаблона). Или же создать свой шорткод в functions.php, а его вывести уже на сайте
    Ответ написан
    7 комментариев
  • Как сделать список одного select зависимым от выбора в другом?

    azerphoenix
    @azerphoenix
    Java Software Engineer
    Добрый день!
    Во-первых, backend тут ни причем. Это все решается на стороне front-end.
    Я бы сказал, что JS обязателен к использованию, а точнее можно обойтись готовыми библиотеками типа select2 или bootstrap-select
    Вот, вариант реализации без js библиотеки
    https://stackoverflow.com/questions/4480637/how-to...
    Ответ написан
  • Как удалить пост с помощью get запроса?

    azerphoenix
    @azerphoenix
    Java Software Engineer
    Здравствуйте!

    При нажатии на кнопку должен удаляться пост. Мне сложно сориентироваться как правильно это сделать.


    Давайте разделим работу на несколько условных частей и разберем поотдельности.
    1) Back-end.
    Создайте сервлет, который будет обрабатывать ваши get запросы на удаление записи.
    Например, структура запроса должна быть примерно такой:
    /posts/delete/{id}
    Конечно, правильнее было бы сделать урл иной структуры, но пока не будем на этом зацикливаться. В данном случае {id} это id поста, который нужно удалить.
    Соответственно, получаете запрос из фронта и достаете из урла id статьи.
    Далее обращаетесь в базу данных (скорее всего вы используете jdbc). Находите статью по этому id и удаляете ее.

    2) Front-end
    Вам из фронта нужно выполнить запрос на удаление статьи.
    Судя по вашему коду <c:forEach var="post" items="${postList}"> у вас выводится некий цикл (список) статей.
    А эта кнопка предназначена для удаления статьи.
    <a class="btn btn-primary btnPost" role="button">Delete</a>


    Измените кнопку и добавьте в нее href атрибут, в котором укажите url на который нужно сделать запрос и id поста, который вы получаете отсюда post.getId()
    Ответ написан
    Комментировать
  • Какой из этих авторов книг по Java, по вашему мнению, пишет проще всего (для новичка): Эккель, Блох, Хорстманн?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    Если хотите прочитать что-то после Java Head First, то пожалуй стоит прочитать:
    1) Герберт Шилдт - Руководство по Java для начинающих.
    2) Герберт Шилдт - Полное руководство по Java.
    По идее можно сразу начать читать вторую книгу.
    Ответ написан
    1 комментарий
  • Как считать данные из json файла и ввести на экран?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Приветствую!

    Тут у вас массив объектов состоящий из 5 элементов.
    [
      {"id": "1", "value": "One"},
      {"id": "jam", "value": "it`s bla-bla"},
      {"id": "abc", "value": "lowercase letter"},
      {"id": "ABC", "value": "uppercase letter"},
      {"id": "2", "value": "two"}
    ]


    Data data = gson.fromJson(reader, Data.class);
    А тут вы создаете лишь один объект. Скорее всего вам нужно получить list объектов.

    Для Gson прочитайте эту статью:
    https://howtodoinjava.com/gson/gson-parse-json-array/

    Обратите внимание на:
    [
        {
          "name": "Alex",
          "id": 1
        },
        {
          "name": "Brian",
          "id": 2
        },
        {
          "name": "Charles",
          "id": 3
        }
    ]


    Вот, тут считывается в массив объектов
    User[] userArray = gson.fromJson(userJson, User[].class);
    Ответ написан
    Комментировать
  • Как в Vue 3 работать с яндекс картами?

    azerphoenix
    @azerphoenix
    Java Software Engineer
    Пробовали работать с картой через этот компонент?
    Vue Yandex Maps
    Ответ написан
    Комментировать
  • Веб-приложение на Java без знаний фронтенда?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    Прекрасно понимаю вас, так как сам когда-то был в подобной ситуации.
    Создавать более или менее нормальные сайты не зная основ - невозможно!
    Если брать по минималке, то разберитесь в:
    - html 5 (посмотрите на блочную верстку и на флексбоксы (flexbox), обратите внимание на тег form )
    - css3 изучите основы css. Изучите бутстрап (bootstrap 3 или 4)
    - изучите javascript & jQuery. Желательно сразу изучить синтаксис ES6
    - изучите основы TCP / IP
    Знаний из этого источника должно быть предостаточно - https://www.w3schools.com/
    Пройдите learn html, learn css и пожалуй, learn bootstrap. JavaScript и jQuery

    Этого должно быть предостаточно, чтобы писать MVC сайты. А если преуспеете в этом деле, то можете потом переходить на js фреймворки (для новичков подойдет VueJS) + RESTful backend.
    Ответ написан
    2 комментария
  • Как создать разные классы под разные роли в Spring Security?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Я бы не создавал классы для каждой из роли, а реализовал бы следующим образом:
    1) Создать класс User. Пометить @MappedSuperclass. Вынести туда общие поля: username, password и др.
    2) Далее создать нужные классы и расширить класс User. Например, Customer, Author и др. И все поля специфичные для каждого из классов указать в них.
    3) Далее можно например, создать паттерн Builder, который при создание сущности по дефолту будет назначать соответствующие классу роли.

    P.S. Не забудьте также имплементировать интерфейс UserDetails нужный для Spring Security.
    Ответ написан
    2 комментария
  • Как сделать exe файл java?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!

    Собственно вопрос, как решить данную проблему?

    Вот, ссылка-ответ на ваш первый вопрос
    https://stackoverflow.com/questions/50075705/jni-e...

    И возможно ли вообще перекинуть потом этот ехе файл чтобы он работал на пк без JDK?

    Вот, ссылка-ответ на ваш вопрос:
    https://eax.me/java-without-jvm/
    Ответ написан
    Комментировать
  • Как работать с изображениями в веб-приложениях на Java?

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

    Как хранить изображение? Насколько я знаю, их можно запихивать прямо в PostgreSQL, но я склоняюсь в сторону того, что изображения надо сохранять в ресурсы, а в бд хранить только ссылки.

    Не самая лучшая идея хранить картинки в виде binary в БД. Лучше, как вы отметили в БД хранить ссылку на объект, а ресурс в файловой системе. Можно хранить файлы в распределенных файловых системах (AWS, Google), но вряд ли вы располагаете таким бюджетом.

    Вот, простая реализация хранения картинок в FS.

    Entity
    @Entity
    @Data
    @NoArgsConstructor
    @Table(name = "attachments")
    public class Attachment {
    
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE)
      private Long attachId;
    
      private String attachTitle;
    
      @Column(nullable = false, updatable = false)
      private LocalDate uploadDate;
    
      private String extension;
    
      private String downloadLink;
    
    }


    Repository
    @Repository
    public interface AttachmentRepository extends JpaRepository<Attachment, Long> {}


    Service
    public interface AttachmentService {
    
      /**
       * Загрузить новый файл
       *
       * @param file
       * @param user
       * @throws IOException
       */
      Attachment addAttachment(MultipartFile file, User user) throws IOException;
    
    
      /**
       * Найти Вложение по его ID
       *
       * @param attachId
       * @return
       */
      Attachment findAttachById(Long attachId);	
    
      /**
       * Скачать файл
       *
       * @param uploadYear
       * @param fileName
       * @return
       * @throws MalformedURLException
       */
      Resource loadFileAsResource(String uploadYear, String fileName) throws MalformedURLException;
    
    }


    ServiceImpl
    @Service
    @RequiredArgsConstructor
    public class AttachmentServiceImpl implements AttachmentService {
    
      private final AttachmentRepository attachmentRepository;
      private final AppProperties appProperties;
      private final FileTools fileTools;
    
      /**
       * Загрузить новый файл
       *
       * @param file
       * @param user
       * @throws IOException
       */
      @Override
      public Attachment addAttachment(MultipartFile file, User user) throws IOException {
        // Создаем директорию если ее не существует
        File uploadDir = new File(appProperties.getUploadPath());
        // Если директория uploads не существует, то создаем ее
        if (!uploadDir.exists()) {
          uploadDir.mkdirs();
        }
        String curDate = LocalDateTime.now().toString();
        // Создаем уникальное название для файла и загружаем файл
        String fileName =
            "attach_" + curDate + "_" + file.getOriginalFilename().toLowerCase().replaceAll(" ", "-");
        file.transferTo(new File(uploadDir + "/" + fileName));
        Attachment attachment = Attachment.builder()
            .attachTitle(fileName)
            .uploadDate(LocalDate.now())
            .extension(fileTools.getFileExtension(file.getOriginalFilename()))
            .downloadLink("/attachments/get/" + Year.now() + "/" + fileName)
            .build();
        attachmentRepository.save(attachment);
        return attachment;
      }
    
    
      /**
       * Найти Вложение по его ID
       *
       * @param attachId
       * @return
       */
      @Override
      public Attachment findAttachById(Long attachId) {
        return attachmentRepository
            .findById(attachId)
            .orElseThrow(() -> new AttachmentNotFoundException("Attachment not found!"));
      }
    
    
      /**
       * Скачать файл
       *
       * @param fileName
       * @return
       * @throws MalformedURLException
       */
      @Override
      public Resource loadFileAsResource( String fileName)
          throws MalformedURLException {
        Path fileStorageLocation =
            Paths.get(appProperties.getUploadPath()).toAbsolutePath().normalize();
        Path filePath = fileStorageLocation.resolve(fileName).normalize();
        return new UrlResource(filePath.toUri());
      }
    
    }


    Conroller
    @Controller
    @RequiredArgsConstructor
    @RequestMapping("/attachments")
    public class AttachmentController {
    
      private final AttachmentService attachmentService;
      private final UserService userService;
    
      /**
       * Загрузить новое вложение
       *
       * @param file
       * @return
       * @throws IOException
       */
      @PostMapping(value = "/add", produces = "application/json")
      @ResponseBody
      public ResponseEntity<Map<String, String>> uploadAttachment(
          @RequestPart(value = "file") MultipartFile file)
          throws IOException {
        Attachment attachment = attachmentService.addAttachment(file);
        Map<String, String> attachmentStatus = new HashMap<>();
        attachmentStatus.put("status", "ok");
        attachmentStatus.put("attachId", attachment.getAttachId().toString());
        return ResponseEntity.ok(attachmentStatus);
      }
    
      /**
       * Получить ссылку на скачивание загруженного файла
       *
       * @param filename
       * @param request
       * @return
       * @throws IOException
       */
      @GetMapping("/get/{filename:.+}")
      public ResponseEntity<Resource> serveFile(
           @PathVariable String filename, HttpServletRequest request)
          throws IOException {
        Resource resource = attachmentService.loadFileAsResource(filename);
        String contentType;
        contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
        if (contentType == null) {
          contentType = "application/octet-stream";
        }
        return ResponseEntity.ok()
            .contentType(MediaType.parseMediaType(contentType))
            .header(
                HttpHeaders.CONTENT_DISPOSITION,
                "attachment; filename=\"" + resource.getFilename() + "\"")
            .body(resource);
      }
    }
    Ответ написан
    4 комментария
  • Как сделать то же самое к другой роли пользователя?

    azerphoenix
    @azerphoenix
    Java Software Engineer
    Добрый день!
    Увы, давно не занимаюсь разработкой на Wordpress.
    Замечу, что делать чат на http очень плохая идея. Лучше поднять чат на сокетах или же как вариант подключить сторонний сервис (например, jivochat).
    На ваш вопрос в силу того, что он вырван из контекста смогу ответить общими словами.
    Во-первых, вам нужно проитерировать по списку учеников, а затем выполнить для каждого из них sql запрос в БД.
    Насколько я понимаю у вас используется ACF Repeater.
    if( have_rows('ucitelya', 'user_' . $user->ID) ) {
                            while (have_rows('ucitelya', 'user_' . $user->ID)) {

    Соответственно, вам нужно создать новый repeater для учеников. Т.е. вместо ucitelya передать уже учеников.
    Далее на этом уровне тоже подправить sql запрос, чтобы он делал выборку и возвращал количество непрочитанных для каждого из учеников
    $total = $wpdb->get_row( "
                                          SELECT COUNT(id) as total
                                          FROM  `wp_school_chat`
                                          WHERE service LIKE '".get_sub_field('direction')."' AND sender = '".$user->ID."' AND recipient = '".get_current_user_id()."' AND is_read = 0
                                    ");

    В общем, надо продебажить проект. Посмотреть что возвращает каждый из ваших полей в указанном вами коде, а затем уже добавить новый функционал. Увы, со стороны сложно что-то конкретное ответить
    Ответ написан
  • Картинки на wordpress имеют такие надпись в конце ?v=1610828339?

    azerphoenix
    @azerphoenix
    Java Software Engineer
    Здравствуйте!
    Какой-то плагин оптимизации, кеширования или сжатия изображений добавил версионирование.
    В этом нет никакой ошибки.
    Ответ написан
  • Как создать элемент ui в libgdx?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Вот, платный курс на русском по libgdx
    https://www.udemy.com/course/2d-libgdx-java/
    Ответ написан
  • Каким способом лучше извлечь данные из БД?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день, коллега!
    Я бы рекомендовал работать по принципу code first, а не db first. А соответственно, подключить любую ORM библиотеку (Hibernate, MyBatis, EclipseLink) или для android (ormlite, room и др.)
    Уверен, разработка на порядок облегчится.

    Чтобы ответить на перечисленные вами вопросы стоит понять вашу изначальную цель.
    Ответ написан
  • По какому принципу Spring DataJPA обновляет записи в связанных таблицах?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Приветствую, коллега!
    Позволь, внести небольшую лепту в ваш код и отметить следующее:
    CrudCourseRepository

    Наверное, указывать Crud в названии не нужно, так как в репозиторий в будущем могут быть добавлены другие методы и соответственно, с точки зрения clean code название не будет корректным.

    Как JpaRepository производит обновление связей в таблице student_courses?

    Как говорится, лучше один раз увидеть, чем сто раз услышать. Так что лучше включить в properties
    spring.jpa.show-sql=true
    spring.jpa.properties.hibernate.format_sql=true


    Предположу, что вы увидите примерно следующее:
    Запрос на SELECT (выборку) из двух таблиц вместе с JOIN, а далее запрос на вставку новой записи (INSERT)

    Насколько я понимаю, если я попытаюсь обновить сущность Student, передав в CrudStudentRepository#save() студента с пустым списком курсов, то в таблице student_courses будут удалены все записи, в которых фигурирует обновляемый студент, но по моему опыту этого не происходит. Как мне тогда удалять/обновлять эти записи?

    Тут пожалуй, вам стоит обратить внимание на CascadeType.

    Например, если в связи OneToMany вы постараетесь сохранить список со стороны самой сущности, то элементы списка будут сохранены, но id у них будет null, так как сама сущность еще не сохранена и ей не присвоен идентификатор. Чтобы избежать этого можно как вариант, указать CascadeType.All или PERSIST & MERGE

    В случае с ManyToMany, думаю, что будет корректным указать тип каскада. Например, CascadeType.PERSIST CascadeType.MERGE

    К слову, есть хороший источник, откуда я также время от времени черпаю информацию. Вот ссылка - link
    Можешь глянуть.
    Ответ написан
    3 комментария
  • Каким образом лучше создать администратора в Spring Boot проекте?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Приветствую, коллега!
    Да, Spring посложнее, чем Django. Но раз тебе удобно писать именно на нем, то конечно же стоит писать backend на нем.
    И да, если уж делать проект по-хорошему, то тебе нужен Spring Security. Тебе нужно создать роль ADMIN.
    Так как проект простой, то можешь использовать In-Memory Auth.
    Так как ты пишешь REST, то скорее всего тебе нужно будет реализовать jwt auth.
    Чтобы по умолчанию при старте приложения создать пользователя, можешь имплементировать интерфейс CommandLineRunner и в методе run() создать юзеров и сохранить в БД.

    P.S. БД необязательно.
    Ответ написан
    Комментировать
  • Возможно ли работать с 3d графикой Java?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Приветствую!
    Да, можно.
    Можно сделать, как Василий Банников предлагает через OpenGL.
    А можно использовать игровые движки и фреймворки
    https://www.lwjgl.org/
    https://libgdx.badlogicgames.com/

    Например, библиотека VTM использует вышеперечисленные библиотеки для отрисовки карты в 3d
    https://github.com/opensciencemap/vtm
    Ответ написан
    Комментировать