Задать вопрос
Ответы пользователя по тегу Spring
  • Не работает удаление записей из БД. Spring boot. В чем проблема?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    У вас тут ошибка:
    @GetMapping(value = "/clients/{clientId/delete}")
    Должно быть:
    @GetMapping(value = "/clients/{clientId}/delete")

    Внимательно читаем логи:

    Error creating bean with name 'ladaController' defined
    No property clientdelete found for type ClientEntity!
    Ответ написан
    Комментировать
  • Как выводить отдельно информацию об определенной записи из БД spring boot?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Добрый день!
    Проблемы могут быть в разных местах, как на клиентской стороне, так и на серверной.
    Исключите следующие ошибки:
    1) С клиентской стороны отправляется корректный GET запрос с id
    /clients/{clientId}
    Например, /clients/6
    2) В контроллере вы принимаете его в виде @PathVariable Integer
    Убедитесь, что у вас в entity Client id задан integer, а не long. Иначе скорее всего будет выброшено исключение.
    3)
    Optional client = null;
    try {
    client = clientRepository.findById(clientId);
    model.addAttribute("allowDelete", false);
    } catch (Exception ex) {
    model.addAttribute("errorMessage", ex.getMessage());
    }
    model.addAttribute("client", client);

    Эту часть кода можно упростить. Например,

    @GetMapping(value = "/clients/{clientId}")
        public String clientDetails(Model model, @PathVariable Integer clientId) {
        Optional client =  clientRepository.findById(clientId).orElseThrow(ClientNotFoundException::new);
        model.addAttribute("client", client);
        return "client-details";
        }


    Но подозреваю, что у вас банальная опечатка.
    В шаблоне вы используете:
    {{#clients}}
    А в контроллере добавляете - client.
    А значит, должно быть:
    {{#client}}
    Ответ написан
  • Как добавить проверку на ввод в spring boot application?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Добрый день!
    Обычно принято делать следующим образом:
    1) Добавьте либу spring boot validation - https://www.baeldung.com/spring-boot-bean-validation

    2) Создайте DTO. Например, если у вас есть entity User, то также создайте UserRequestDto.
    Например,
    UserRequestDto {
    @NotBlank(message = "Name is mandatory")
    String username;
    
    @NotBlank(message = "Email is mandatory")
    String email;
    }


    3) Валидируйте отправленные в бекенд данные (dto) при помощи вышеуказанной библиотеки и если что-то не так выбрасывайте исключение MethodArgumentNotValidException

    например,
    //@RestController
    @Controller 
    UserController {
    
    public ResponseEntity<User> addUser( @Valid UserDto user ) {
    // конвертируем UserDto -> User и в передаем в сервисный класс для сохранения
    }
    
    }


    Также валидацию можно сделать на клиентской стороне средствами JavaScript или HTML.
    Средствами html можно для инпутов добавить required, указать тип инпута например, <input type="email" />

    P.S. Кстати, у вас в entity NotNull импортирован import com.sun.istack.NotNull;, а должно быть hibernate validator.
    Ответ написан
    8 комментариев
  • Как скрыть поле для Админа от глаз обычного пользователя?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    Предположу, что вы подключили к вашему приложению Spring Security и у вас есть уже определенные роли. Например, user & admin.
    Теперь, чтобы в шаблонизаторе (thymeleaf) проверить роль или привилегию юзера вам нужно подключить либу "thymeleaf extras spring security"
    https://github.com/thymeleaf/thymeleaf-extras-spri...
    Ну а дальше по ссылке выше есть документация, читаем ее.
    Например,
    <div sec:authorize="hasRole('ROLE_ADMIN')">
      This will only be displayed if authenticated user has role ROLE_ADMIN.
    </div>
    Ответ написан
  • Как реализовать фронт на Rest api?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Как отметил коллега, это делается через js-фреймворк. Если хотите изучить js-фреймворк, то простым фреймворком является VueJS. Можете начать с него. Ну разумеется, что знание JavaScript или TypeScript обязательно.
    Ответ написан
    Комментировать
  • Как организовать сложное DTO из нескольких сущностей?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Ну можно создать несколько DTO по аналогии с нужными сущностями из БД.
    Например,
    class User {
    Role role;
    }
    class Role {
    List<Privilege> privileges;
    }
    
    class UserDto {
    RoleDto role;
    }
    class RoleDto {
    List<PrivilegeDto> privileges;
    }


    Если названия совпадают, то мапперы смогут сковертировать Dto <--> Entity, в ином случае надо будет кастомизировать мапперы или добавить соответствующие аннотации. Можно взять тот же MapStruct || ModelMapper или использовать спринговый Converter<>
    Ответ написан
    Комментировать
  • Как связать html-файлы в Spring?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Добрый день!
    Судя по коду вы используете thymeleaf.
    Но я так и не увидел вашего вопроса. Вы создали фрагмент header.html при помощи th:fragment, а затем вставили этот фрагмент при помощи th:insert. А в чем заключается проблема? Что-то не работает или ...?

    И в зависимости от версии thymeleaf th:insert="header :: header" это может не работать или просто выдавать предупреждение. Используйте th:insert="~{header :: header}"

    Есть кстати, доп. либа, которая позволяет более гибко настраивать шаблоны - Thymeleaf Layout Dialect
    https://github.com/ultraq/thymeleaf-layout-dialect

    Полезная информация - https://habr.com/ru/post/351844/
    Ответ написан
    Комментировать
  • Как конфигурировать программу в контейнере снаружи?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    На самом деле вариантов много и ответы можно легко найти, если поискать.
    Вот, несколькие из них:
    Допустим, что вы собираете образ используя Dockerfile. Если вы хотите иметь возможность конфигурировать сам процесс создания image на основе Dockerfile, то посмотрите на такие инструкции, как ARG & ENV. ARG - позволяет определять аргументы на этапе (до создания) image. ENV - environment определяет переменные среды.
    Соответственно, передать эти параметры можно так:
    1) В случае ARG для docker использовать --build-args. В случае ENV использовать -e
    2) В случае использования docker-compose для передачи параметра в Dockerfile использовать environment:
    Например,
    environment:
      - BASE_URL=http://example.com

    3) Если вы хотите передать конфигурацию для application.properties или application.yml извне например, из docker-compose, то можете просто в environment указать нужные конфиги.
    Например,
    environment:
          - spring.application.name=custom_app


    Доп. информация:
    https://stackoverflow.com/questions/46057625/exter...
    https://stackoverflow.com/questions/58695423/pass-...
    https://medium.com/@cybourgeoisie/docker-env-metho...
    Ответ написан
    Комментировать
  • Почему ошибка отправки email с Java 16?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Failed messages: javax.mail.MessagingException: Could not convert socket to TLS;

    Добавьте в props
    props.put("mail.smtp.ssl.trust", "smtp.gmail.com");

    https://stackoverflow.com/questions/16115453/javam...
    Ответ написан
  • Как добавить CSS в Spring Security?

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

    Об этом речь?
    @Override
      public void configure(WebSecurity web) {
        web.ignoring()
            .antMatchers(
                "/css/**", "/fonts/**",
                "/images/**");
      }


    Если используете thymeleaf, то путь прописывать так:

    <link media="all" rel="stylesheet" th:href="@{/css/reset.css}" type="text/css"/>
    Ответ написан
  • Spring Data Jpa как удалить сущность без удаления другой связной сущности?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Добрый день.
    Можете попробовать следующее:
    CascadeType.MERGE,
    CascadeType.PERSIST

    orphanRemovel = false;
    Если orphanRemoval = true, то если у клиента будет отсутствовать lessonId, то он будет удален, так как является "сиротой". А если наоборот false, то удаляться не будет.
    Вот, разница между CascadeType.REMOVE vs orphanRemoval
    https://www.baeldung.com/jpa-cascade-remove-vs-orp...
    Ответ написан
    Комментировать
  • Как в spring посмотреть при дебаге запроса все его параметры?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    В asp.net есть объект HttpRequest через который в контроллере можно увидеть все параметры запроса, начиная от url и заканчивая заголовками и куками. Есть ли подобный аналог в Spring?

    Да, аналог есть - https://docs.spring.io/spring-framework/docs/curre...
    Ответ написан
  • Как сохранить в таблице картинку при изменении других полей?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Как сохранить в таблице картинку при изменении других полей?

    А зачем вы удаляете / изменяете картинку при изменении полей?
    Допустим, что есть некий эндпоинт, куда нужно отправлять POST запрос для загрузки картинки и принимает он MultiPartFile.
    Соответственно, при загрузки новой картинки можно отправить аякс запрос на этот урл, а id картинки назначить для сущности, которая добавляется из формы.
    А значит, при изменении других данных вы никоим образом не будете изменять картинку и соответственно, она не удалится.
    Ответ написан
  • Как отправить запрос на предоставление доступа?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Добрый день!
    Было бы неплохо вообще более подробно описать проблему, чтобы можно было более точно ответить.

    есть файл, у него есть владелец

    Где этот файл находится? Что значит у него есть владелец? Просто, например, файл может лежать где-то на сервере и владельцем его будет являться пользователь Linux или владельцем будет являться пользователь Apache и т.д. Или же под владельцем подразумевается некая сущность юзера, которая реализована в Spring.

    Нужно отправить запрос от другого пользователя на получение доступа.

    Как другой пользователь видит, что у этого пользователя (владельца) есть файл?
    Что является процессом предоставления доступа к этому файлу? Т.е. дать ссылку на скачивание этого файла просто или например, дать доступ на редактирование или только просмотр этого файла (как в Google Drive || Yandex Disk).

    Можно ссылку на документацию или хотя бы название, куда смотреть.

    Ну смотреть нужно в документацию по Spring. А также погуглить ваш вопрос, но с большей детализацией.

    Напишу псевдокодом для наглядности один из простых вариантов решения:
    entity User {
       List<File> uploadedFiles; (OneToMany)
       List<File>  files; (ManyToMany)
    }
    entity File {
       User owner; (ManyToOne)
       List<User> users; (ManyToMany)
    }

    uploadedFiles - файлы загруженные пользователем
    owner - владелец файла
    files - файлы, к которым у пользователя есть доступ
    users - пользователи, у которых есть доступ к этому файлу.


    Дальше процессом предоставления доступа к файлу является уведомление пользователя (например, по почте или через push и т.д.) с просьбой предоставить доступ на указанный файл. Если доступ владельцем предоставляется, то запрашивающий доступ пользователь добавляется в список users для того файла, который он запросил.

    Это самый примитивный вариант, который можно реализовать. Конечно же если предполагается интеграция с AWS, то могут потребоваться дополнительные манипуляции.

    А так для более объективного и детального ответа, нужно больше информации о продукте и цели, которую вы желаете достичь.
    Ответ написан
  • Как реализовать страницу для тестирования учеников?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Во-первых, непонятно в каком объеме у вас на данный момент реализовано текущее приложение на Spring.

    Сайт на подобие визитки.

    И вообще странно, что если это просто сайт-визитка, то зачем она писалась на Spring + VueJS. Там банально CMS WordPress хватит с лихвой. Ну в крайнем случае можно было взять рнр фреймворк (Yii2, Laravel) - обошлось бы дешевле для школы)

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


    1) Эндпоинты для ЛК учителя и ученика должны быть разными.
    2) Эндпоинты аутентификации учителя и ученика тоже можно сделать разными.
    3) Тестирование бывает разным. Нужно для начала разобраться с тем, какое тестирование вам нужно и как его можно реализовать.

    Например, есть тестирование при котором проверяется правильность выбранного ответа. Т.е. пользователь выбрал ответ "а" и соответственно, проверяем корректный ответ, хранимый в БД. Этот тест можно усложнить тем, что каждый раз при прохождении теста изменять местами варианты ответов, чтобы ученики не запоминали ответы по буквам.

    Другой вид тестирования, когда каждому ответу присваивается определенный балл. Далее высчитывается набранная сумма и выдается ему некий результат (часто встречается в психологических тестах).
    Иной вид тестирования, когда проверяется количество выбранных ответов варианта "А", "В" и т.д. Т.е. пользователь выбрал "А" - 5 раз, "В" - 2 раза. И если например, А < 5 и B >2, то отдаем один результат, иначе другой и т.д.

    4)
    Особенно как лучше сделать саму логику обработки ответов и последующую их проверку?

    Например, по мере прохождения теста формируем массив ответов и записываем их в LS, чтобы в случае чего не потерять данные. Затем по сабмиту "отправить на проверку" отправляем массив на сервер и перебирая ответы сравниваем их со значениями в БД. Если предусматривается возможность изменение варианта ответа для того или иного вопроса, то при изменении ответа, вносим правки в массив и сохраняем LS.

    Как реализовать страницу для тестирования учеников?

    Вообще, как по мне тут больше работы с фронтом, нежели с бэком.
    На самом деле тут много нюансов, которые нужно уточнить. Например, должны ли тесты делиться по темам или по каким-то категориями? Сколько тестов всего бывает и сколько из них отдается на клиент? Как корректно сфорировать сущности пользователей, тестов, тематик и т.д.?

    Либо попробуйте поискать готовые решения, которые потом можете встроить в сайт. Правда, не самое лучшее решение.
    Например, https://www.classmarker.com/online-testing/how-to-...
    https://quiz.proprofs.com/how-do-i-embed-a-quiz-on...
    https://www.riddle.com/blog/embed-online-quizzes-site/
    Google

    В общем, все зависит от ваших навыков программирования, от бюджета, от сроков и т.д.
    Самое быстрое решение возможно, использование CMS с готовыми плагинами.
    Например, WordPress + плагины
    https://ru.wordpress.org/plugins/quiz-master-next/
    https://ru.wordpress.org/plugins/wp-quiz/
    https://www.wpbeginner.com/showcase/best-quiz-plug...
    https://ru.wordpress.org/plugins/hd-quiz/
    https://ru.wordpress.org/plugins/quiz-maker/
    Google

    Для более объективного ответа нужно больше данных.
    Ответ написан
    2 комментария
  • Создание и правильный перенос Spring?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день!
    1) Как вы знаете, можно проект запаковать в jar или war. Притом, если запаковать в jar, то в Spring есть встроенный Tomcat (внутри Spring Web), который позволяет быстро деплоить проект на сервере. Если собираете WAR, то исключите из проекта встроенный Tomcat. Соответственно, сам проект нужно будет запускать в уже установленном Tomcat на сервере. Можно пойти чуть дальше и создать образ для Docker, где прописать все необходимые для деплоя конфигурации (например, скачать Tomcat, Maven и т.д.). Все зависит от того, как именно вы хотите развернуть приложение. Конечно же наличие Maven || Gradle Wrapper Будет плюсом. Не забудьте также завести отдельные профили конфигураций (yml или properties) для режима разработки и продакшна.
    2) Принципиальная разница есть. Версии java 8, 11, 17 являются LTS.
    Я слышал, что в версиях Java выше 11 иногда могут быть проблемы со Spring, но сам лично не сталкивался. Обычно рекомендуют использовать java 8 & 11. Но конечно же в более новых версиях Spring тоже должен работать.
    https://www.infoq.com/news/2018/09/spring-51-java-11/
    3)
    Может вы что посоветуете, а то я только начинаю работать с JAVA.

    Сложно что-либо советовать не зная уровня ваших познаний в Java. Если вкратце, то у вас должны быть знания на уровне Java Junior, чтобы вы могли начать разработку на Spring. Укрепите знания в Java SE (jcf, jdbc) & EE (orm, hibernate, jpa, servlet, jsp, jstl). Изучите Spring Framework, а затем Spring Boot и т.д.
    Ответ на ваш вопрос на Хабре давался не один раз. Просто поищите и увидите, что необходимо изучить.
    Ответ написан
  • Что нужно чтобы сделать чат на spring?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Ну если вам нужено простой чат, то можете использовать Spring Websockets
    Вот, в этой статье подробно написано, как это реализовать:
    https://habr.com/ru/company/otus/blog/516702/

    А дальше можете посмотреть в сторону RabbitMQ
    https://spring.io/guides/gs/messaging-rabbitmq/
    https://habr.com/ru/company/otus/blog/500936/
    https://habr.com/ru/post/262069/
    или же ActiveMQ
    activemq.apache.org/spring-support.html
    Ответ написан
    Комментировать
  • Как правильно сделать взаимодействия между модулями в Java Spring?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Добрый день.
    Предположу, что у вас все-таки реализован не микросервисный монолит, а монолитная архитектура. Вы лишь разделили монолитное приложение на модули и подключили их в gradle. С другой стороны - а нужен ли вам микросервисный монолит или микросервис вообще, если приложение довольно маленькое и им пользуются всего 40 человек.
    Если речь идет просто о взаимодействии модулей монолитного приложения, то в соответствующем gradle файле модуля подключаете нужный модуль и импортируете нужные сервисы, классы и т.д.
    Главное обратите внимание, чтобы не было циклической зависимости, которая у вас указана тут:
    Circular dependency between the following tasks:
    :amocrm:compileJava
    \--- :datadeal:compileJava
         \--- :amocrm:compileJava (*)

    Информация по теме -
    https://reflectoring.io/spring-boot-gradle-multi-m...
    https://spring.io/guides/gs/multi-module/
    Циклическая зависимость возникает, когда модуль А ссылается на модуль В, а модул В ссылается на модуль А. Ни gradle, ни maven не могут решить эту проблему, так как для сборки одного модуля нужен другой модуль, а для другого первый. Также это говорит о том, что возможно проект был несовсем корректно разделен на модули. Можно попробовать создать модуль C, и вынести общие для модулей A & B классы в него. А затем добавить зависимость модуля A от C, а модуля B тоже от C. Таким образом циклической зависимости не будет. Также обратите внимание на рекомендации по организации структуры Spring приложения, которая указана в оф. документации на их сайте.

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

    Если уж вам понадобилось делить проект на микросервисы, то как по мне лучше реализовать полноценную микросервисную архитектуру через API Gateway. Соответственно, связать модули через REST. Тут уже понадобится Spring Cloud API Gateway, Spring Cloud Netflix Eureka Client & Server и т.д.

    Возможно, что есть подводные камни, о которых я не знаю. Надеюсь, что коллеги поопытнее более подробно ответят на данный вопрос.
    А так вот, небольшая статья по данной тематике: https://habr.com/ru/post/496934/
    Вдруг, вам будет интересно - небольшой вводный курс по Spring Cloud, Eureka, Zulu и т.д. - https://www.udemy.com/course/spring-boot-microserv...
    Ответ написан
    1 комментарий
  • Persistable или AbstractPersistable?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Interface Persistable<ID>
    Persistable - это интерфейс.

    Class AbstractPersistable<PK extends Serializable>
    AbstractPersistable - это абстрактный класс, который имплементирует интерфейс Persistable. В силу того, что это класс, то методы equals() & hashcode() уже реализованы в нем.

    По поводу того, что нужно использовать, вот, выдержка из документации Spring:

    AbstractPersistable is a one-stop shop for very basic use cases. The only thing it actually does is setting up default id generation. If you want to customize that, there's nothing you gain from extending the class. So we generally recommend to neither extend the class nor implement Persistable unless you really need to customize when Spring Data shall consider the entity new.


    https://docs.spring.io/spring-data/data-jpa/docs/c...
    https://docs.spring.io/spring-data/commons/docs/cu...
    Ответ написан
  • Как настроить проект, чтобы он поднимал схему в БД с использованием hibernate?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Добрый день.
    Размещение доступов к БД внутри Java не рекомендуется.
    private static final String URL = "jdbc:mysql://localhost:3306/library_project?serverTimezone=UTC";
        private static final String USER = "root";
        private static final String PASSWORD = "root";

    Лучше вынести его в properties или yml
    Вот, пример:
    spring.jpa.hibernate.ddl-auto=update
    spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_example
    spring.datasource.username=springuser
    spring.datasource.password=ThePassword


    https://spring.io/guides/gs/accessing-data-mysql/
    https://www.baeldung.com/java-connect-mysql

    Также остаётся загадкой, как запустить проект, чтобы проверить работоспособность хоть чего-нибудь, ведь Main с psvm-ом здесь быть не должно, если я верно всё понимаю.


    @SpringBootApplication
    public class Application {
    
    	public static void main(String[] args) {
    		SpringApplication.run(Application.class, args);
    	}
    
    }
    Ответ написан
    Комментировать