Как запустить spring приложение
Этот урок показывает пример того, как Spring Boot помогает вам ускорить и облегчить разработку приложений. Из учебных материалов вы увидите случаи использования Spring Boot. Если вы хотите создать проект на его основе, то посетите Spring Initializr, заполните онформацию о проекте, выберите опции и вы сможете загрузить файл сборки Maven, либо Gradle, либо как проект в виде zip-файла.
Что вы создадите
Вы создадите простое web-приложение с Spring Boot и добавите в него несколько полезных сервисов.
Что вам потребуется
- Примерно 15 минут свободного времени
- Любимый текстовый редактор или IDE и выше
- Gradle 1.11+ или Maven 3.0+
- Вы также можете импортировать код этого урока, а также просматривать web-страницы прямо из Spring Tool Suite (STS), собственно как и работать дальше из него.
Как проходить этот урок
Как и большинство уроков по Spring, вы можете начать с нуля и выполнять каждый шаг, либо пропустить базовые шаги, которые вам уже знакомы. В любом случае, вы в конечном итоге получите рабочий код.
Чтобы начать с нуля, перейдите в Настройка проекта.
Когда вы закончите, можете сравнить получившийся результат с образцом в gs-spring-boot/complete .
Настройка проекта
Для начала вам необходимо настроить базовый скрипт сборки. Вы можете использовать любую систему сборки, которая вам нравится для сборки проетов Spring, но в этом уроке рассмотрим код для работы с Gradle и Maven. Если вы не знакомы ни с одним из них, ознакомьтесь с соответсвующими уроками Сборка Java-проекта с использованием Gradle или Сборка Java-проекта с использованием Maven.
Создание структуры каталогов
В выбранном вами каталоге проекта создайте следующую структуру каталогов; к примеру, командой mkdir -p src/main/java/hello для *nix систем:
Создание файла сборки Gradle
Ниже представлен начальный файл сборки Gradle. Файл pom.xml находится здесь. Если вы используете Spring Tool Suite (STS), то можете импортировать урок прямо из него.
Если вы посмотрите на pom.xml , вы найдете, что указана версия для maven-compiler-plugin. В общем, это не рекомендуется делать. В данном случае он предназначен для решения проблем с нашей CI системы, которая по умолчанию имеет старую(до Java 5) версию этого плагина.Spring Boot gradle plugin предоставляет множество удобных возможностей:
- Он собирает все jar'ы в classpath и собирает единое, исполняемое "über-jar", что делает более удобным выполнение и доставку вашего сервиса
- Он ищет public static void main() метод, как признак исполняемого класса
- Он предоставляет встроенное разрешение зависимостей, с определенными номерами версий для соответсвующих Spring Boot зависимостей. Вы можете переопределить на любые версии, какие захотите, но он будет по умолчанию для Boot выбранным набором версий
Узнайте, что вы можете делать с Spring Boot
Spring Boot предлагает быстрый путь для создания приложений. Он просматривает ваш classpath и бины, которые вы сконфигурировали, делает предположения о том, что нехватает и добавляет их. С Spring Boot вы можете сконцентрироваться больше на решении бизнес задач и меньше на инфраструктуру.
- Требуется Spring MVC? Некоторые определенные бины вам почти всегда необходимы и Spring Boot добавит для них автоматически. Spring MVC приложению также необходим сервлет контейнер, поэтому Spring Boot автоматически настроит встроенный Tomcat
- Требуется Jetty? Если так, то скорее всего вам не нужен Tomcat, а вместо него нужен встроенный Jetty. Spring Boot обработает эту задачу для вас
- Требуется Thymeleaf? Для этого несколько бинов должны всегда быть добавлены в контекст вашего приложения; Spring Boot добавит их для вас
Это лишь несколько примеров, которые предоставляет автоманическая настройка Spring Boot. В то же время, Spring Boot не заработает с вашими настройками. Например, если Thymeleaf в вашем classpath, то Spring Boot добавит SpringTemplateEngine в ваш контекст приложения автоматически. Но если вы определите свой собственный SpringTemplateEngine с вашими настройками, то Spring Boot не добавит его. Это останется под вашим контролем и потребует от вас немного усилий.
Spring Boot не генерирует код и не редактирует ваши файлы. Вместо этого, когда вы поднимаете ваше приложение, Spring Boot динамически инициализирует бины и настройки и применяет их к вашему контексту приложения.Создание простого web приложения
Теперь вы можете создать web контроллер для простого web приложения.
Класс помечен как @RestController , означая, что он готов к использованию Spring MVC для обработки запросов. RequestMapping соответствует / метода index() . При вызове из браузера или использовании curl в командной строке, метод возвращает чистый текст. Т.к. @RestController сочетает в себе @Controller и @ResponseBody , две аннотации в результате web запросов возвращают данные, а не представление.
Создание Application класса
Здесь вы создаете Application класс с компонентами:
- @Configuration помечает класс как источник определения бинов для контекста приложения
- @EnableAutoConfiguration говорит Spring Boot о запуске добавления бинов в соответствии с содержанием classpath и других бинов, а также различных параметров настроек
- Обычно вы добавили бы @EnableMVC для Spring MVC, но Spring Boot добавляет её автоматически, когда видит spring-webmvc в classpath. Этот флаг помечает приложение как web приложение и активирует ключевые действия, такие как настройка DispatcherServlet
- @ComponentScan говорит Spring о том, чтобы просмотреть все компоненты, конфигурации и сервисы в пакете hello , сто позволяет ему найти HelloController
Метод run() возвращает ApplicationContext и этому приложению отдаются все бины, которые были созданы вашим приложением или автоматически добавлены благодаря Spring Boot. Метод сортирует бины и печатает их имена.
Запуск приложения
Для запуска приложения выполните:
Если вы используете Maven, то:
Вы должны увидеть примерно такое:
Вы можете явно видеть org.springframework.boot.autoconfigure бины. А также tomcatEmbeddedServletContainerFactory .
Добавление сервисов бизнес-уровня
Если вы создаете web-сайт для вашего бизнеса, то вам скорее всего необходимо добавить некоторые сервисы для управления. Spring Boot предоставляет несколько таких "из коробки" в одном из своих модулей, таких как состояние, аудит, бины и другие.
Добавьте это в список зависимостей вашего файла сборки:
Если вы используете Maven, то добавьте это в список зависимостей:
Затем перезапустите приложение:
Если вы используете Maven, то:
Вы увидите новый набор RESTful точек выхода, добавленных в приложение. Это сервисы управления, предоставленные Spring Boot:
Также есть /shutdown , но она видна по умолчанию только через JMX. Для включения её к общедоступным, добавьте endpoints.shutdown.enabled=true в ваш application.properties файл.это легко проверить по состоянию приложения:
Вы можете попытаться вызвать завершение работы через curl:
Т.к. мы не включили его, запрос блокирован, потому что его не существует.
Более подробную информацию о каждом из этих REST сервисов и о том, как вы можете настраивать под себя в application.properties , вы можете прочитать в документации.
Просмотр Spring Boot starters
Последний пример показал как Spring Boot упрощает инициализацию бинов, о которых вы не знаете, что они вам нужны. И он показал, как подклюсить удобные для управления сервисы.
Но Spring Boot делает ещё большее. Он поддерживает не только традиционное использование WAR файлов, но также сборку исполняемых JAR файлов, благодаря модулю загрузчика Spring Boot. Различные уроки демонстрируют эту двойную поддержку через spring-boot-gradle-plugin и spring-boot-maven-plugin .
ко всему прочему, Spring Boot поддерживает Groovy, позволяя вам создавать Spring MVC приложения в небольшом и единственном файле.
Создайте новый файл app.groovy и поместите в него приведенный ниже код:
Не имеет значения, где расположен файл. Можете даже гордится приложением, как мало нужно всего лишь для единственного твита! Предполагается, что вы завершите предыдущее приложение во избежание конфликта портов.Давайте проверим, что получилось:
Spring Boot динамически добавляет аннотации к вашему коду и использует Groovy Grape для подтягивания необходимых для запуска приложения библиотек. Смотрите документацию, если хотите копнуть шлубже.
Поздравляем! Вы только что создали простое web приложени с использованием Spring Boot и изучили как нарастить ваш темп разработки. вы также настроили некоторые удобные сервисы. Это только малая часть того, что может делать Spring Boot.
В данной статье я попробую расписать все шаги, которые потребуются для создания небольшого проекта на Spring Boot и развертывания его на боевом сервере.
Не будем тянуть долгими прелюдиями о философии java и spring'а, и сразу приступим к делу.
Для начала нам необходимо создать каркас приложения, внедрив туда весь необходимый зоопарк технологий(как минимум Spring, JPA, JDBC). До появления spring boot нужно было потратить на это немало времени, если конечно у вас не было рабочей заготовки в закромах кода. И именно сложность создания подобного каркаса, как мне кажется, останавливает многих от разработки небольших веб-проектов на java. Конечно, когда-то был хромой spring roo, который мог создать подобный каркас в ущерб производительности(привет аспектам), но даже с ним количество и сложность конфигурационных файлов заставляли долго медитировать над ними неподготовленного разработчика. Однако теперь с приходом Boot и Spring 4 жизнь стала немного проще и количество конфигурационных файлов заметно уменьшилось.
Если у вас есть Intellij Idea 14.1, то проблем с каркасом возникнуть вообще не должно, можно все сделать через специальный мастер создания проектов(File-New-Project. -Spring Initializr). Далее останется только указать названия проектов, выбрать интересующие нас технологии(Web, JDBC, JPA, PostgreSQL) и создать проект.
Если же у вас нет данной IDE, то скачиваем Spring Boot CLI, следуем инструкции в INSTALL.txt. Нужно задать системную переменную SPRING_HOME(путь к папке со Spring Boot, не к папке bin!) и добавить путь к SPRING_HOME/bin в системную переменную PATH на windows.
Итак, консоль спринга настроили, теперь самое время создать проект. Сделать это можно следующей командой:
UPDATE
Кроме того, как написали в комментариях, существует еще веб-конструктор: start.spring.io
Далее импортируем получившийся каркас в любимую IDE и начинаем его модифицировать под наши нужды.
Для начала добавим в каталог src/main папку webapps. Все веб-ресурсы мы будем создавать в ней, а не в папке resources, как хочет того спринг. Дело в том, что если мы будем создавать файлы в папке resources, то тогда мы лишимся возможности видеть изменения, сделанные в наших веб-ресурсах, без перезагрузки сервера. А это может быть неприятно, когда ради того, чтобы посмотреть изменившийся текст на веб-странице приходится перезапускать веб-сервер.
Теперь в папке webapps создаем файл index.html и папки css, js, font, images, в которые будем класть соответствующие ресурсы.
Для примера сделаем самый простой каркас index.html:
Изменим файл pom.xml
Должно получиться что-то подобное:
Мы используем postgresql 9.4(тоже неплохо бы установить его локально на свою машину). Connection pool для взаимодействия с базой данных мы берем самый модный и производительный (HikariCP). Кроме того, мы используем специальный плагин, который, когда мы будем генерировать итоговый jar'ник, перенесет все наши данные из webapp в resources/static, как того хочет spring boot. В противном случае вы не сможете увидеть все те веб-страницы, что создадите в папке webapps, когда запустите jar-ник.
Добавим пакет config и создадим в нем класс JpaConfig:
Кроме того, добавим в файл application.properties следующие строчки:
И наконец в Application.java меняем строку инициализации на следующую:
Тем самым мы настроили подключение к СУБД PostgreSQL.
Не забываем создать саму базу данных и простенькую таблицу в ней. Сделать это удобнее всего через PgAdmin.
Создав в ней пустую базу yourapp_data, выполняем скрипт создания таблицы:
Теперь настало время немного заняться начинкой нашего проекта. А именно добавить какую-нибудь сущность БД и научиться с ней работать, получая с клиента данные для ее формирования и отправляя клиенту же данные об уже созданных сущностях.
Создаем пакеты controller, entity, repository, service, utils.
В пакете entity создаем интерфейс:
Аннотации JPA и Hibernate в данном примере использовать не будем, так как эти технологии сильно замедляют работу(запрос может выполняться в 10 раз медленнее, чем на чистом jdbc), а так как у нас нет сильно сложных сущностей, для которых реально может потребоваться ORM, то воспользуемся обычным jdbcTemplate.
Создаем интерфейс репозитория:
И его реализацию:
Вместо уже упомянутого jdbcTemplate, мы, как видите, используем JdbcOperations, который является его интерфейсом. Нам приходится использовать везде интерфейсы, отделяя их от реализации, так как, во-первых это стильно, модно, молодежно, а во-вторых, spring в нашем случае использует стандартный jdk'шный Proxy для наших объектов, поэтому напрямую инжектить реализацию не получиться, пока мы не введем полноценные аспекты и AspectJ compile-time weaving. В нашем случае этого и не требуется, чтобы не перегружать приложение.
Осталось уже немного. Создаем наш сервис(мы же хорошие разработчики и должны отделить бизнес-логику от логики работы с СУБД?).
Отлично. Теперь создаем пару вспомогательных классов, необходимых для реализации контроллера:
Это наша реализация Exception'а. Может пригодиться в будущем, хотя и не обязательна, но на нее завязан следующий класс:
Если мы словили такую ошибку в нашем контроллере, то она будет обработана дополнительно в этом методе.
Наконец напишем небольшой классик, который будет формировать структуру данных для передачи на клиент:
Все, со вспомогательными классами закончили. Осталось написать наш контроллер. Он будет простым, как пробка:
В нем два метода — сохранить полученные данные и выдать порцию случайных данных на клиент. Контроллер унаследован от созданного нами ранее ExceptionHandlerController. Обработка исключений написана только как шаблон и нуждается в соответствующей доработки под себя.
Итак, основная часть серверного кода написана, осталось проверить его работу на клиенте. Для этого нужно доработать наш файл index.html и заодно добавить библиотеку jquery в каталог js.
index.html:
Однако рано или поздно вы сотворите желаемое и встанет вопрос о том, как донести ваше детище в массы. Об этом будет вторая часть статьи.
Этот сервис позволит бесплатно зарегистрировать домен в зонах .tk, .ml, .ga, .cf, .gq
Да, не самые лучшие зоны, но:
Отлично, у нас есть сервер, пора залить на него наш проект.
Для начала собираем проект maven'ом. Сделать это можно через IDE или же на худой конец зайдя в корневую директорию проекта и введя команду mvn clean install(путь к мавену должен быть прописан в системой переменной path на Windows). После выполнения команды собранный jar'ник помещается в локальный репозиторий (по умолчанию именуемый .m2), откуда его можно стянуть для отправки на сервер.
Для передачи файла на сервер используем WinSCP, если вы работаете под Windows.
Далее заходим на наш сервер, используя putty на Windows или ssh на Linux.
Переходим в директорию, куда был скопирован наш jar-ник и пробуем его запустить командой java -jar youapp.jar
Скорей всего, не получилось. А все почему? Наш проект был создан на java 8, а какая java стоит на сервере, можно узнать с помощью команды java -version. И скорей всего это либо 6, либо 7.
Но не будем унывать, поставим себе новую версию:
Теперь настала очередь postgres'а. До этого мы использовали локальную версию на машине разработчика, теперь пришло время поставить СУБД на сервер.
Для этого сначала выполняем магическую последовательность команд:
Далее выполняем команду входа в psql:
И выходим c помощью команды \q
Затем редактируем файл /etc/postgresql/9.4/main/pg_hba.conf
Должны быть добавлены две новых строчки и изменена одна строка для 127.0.0.1 следующим образом:
Я намеренно изменил md5 на trust, так как лично у меня были проблемы с запуском проекта, тем самым отключив проверку пароля для заданных адресов. Возможно у вас их не будет.
Теперь все настроено. Хотя тюнинговать постгрес можно до бесконечности, но ведь у нас всего лишь маленький проект, а значит, пока оставим как есть.
Перезапускаем postgres: и проверяем его работу.
Всё, с настройкой postgres'а закончили, что у нас дальше по сценарию?
Как уже было отмечено ранее, для запуска собранного jar'ника вполне достаточно команды java -jar youapp.jar
Однако при подобном запуске для того, чтобы зайти на сайт извне, придется прописывать порт(по умолчанию 8080). Чтобы пользователи смогли зайти на сайт, просто введя его адрес, то нам потребуется прокси сервер. В качестве него можно взять nginx, который нужно будет предварительно настроить.
В моем случае корневой директорией nginx была /etc/nginx. Там нам в первую очередь потребуется изменить файл /sites_available/default следующим образом:
Однако и это еще не все. Необходимо также модифицировать наш проект, чтобы он поддерживал настроенный нами прокси. Благо сделать это не трудно, достаточно лишь в application.properties добавить строки(не забудьте залить новую версию с изменениями):
Теперь можно запустить nginx командой service nginx start и затем попробовать запустить наш проект. Он будет доступен по ссылке сайта, либо же, если вы еще не приобрели домен, то по его ip-адресу, без указания порта.
Остался еще один небольшой штрих. Немного неудобно всегда стартовать проект тем способом, который был описан выше. Неплохо бы, чтобы при старте проекта консоль ввода на сервере освобождалась, приложение не закрывалось бы после выхода из ssh-сессии и чтобы где-нибудь велись логи приложения. Сделать это можно с помощью команды nohup. Предварительно создаем bash-скрипт, называя его script.sh:
Прописываем ему право на исполнение:
И запускаем командой:
Все, приложение запущено.
Чтобы остановить приложение, можно либо воспользоваться командой pkill -9 java(при условии, что это единственное java-приложение, запущенное на сервере), либо с помощью утилиты htop, выделив этот процесс, нажав кнопку F9, выбрав слева в списке SIGKILL и нажав enter. На заметку: иногда не срабатывает с первого раза и процедуру приходится повторять.
Теперь, если все сделано правильно, можно открыть сайт нашего проекта в браузере и насладиться результатом.
Открываем Intellij IDEA и создаем новый Maven проект:
После создания проекта идем на сайт Spring в раздеп Guides:
Далее в строке поиска пишем MVC и получаем такой результат:
Заходим по этой ссылке и делаем все, что там написано (далее по тексту).
Конфигурация pom.xml для Spring Boot
Чтобы сконфигурировать Spring Boot проект нам надо прописать build script:
Создаем файлы проекта Spring Boot
Далее по инструкции создаем пакет hello и в нем класс GreetingController:
Содержимой класса выглядит следующим образом:
Далее в ресурсах создаем папку templates и в ней файл greeting.html, имеющий следующее содержимое:
Далее в пакете hello создадим класс Application:
Далее создаем папку static в ресурсах и в ней создаем файл index.html:
Запуск Spring Boot приложения
Чтобы запустить приложение, надо перейти в класс Application и выполнить действия, показанные на скриншоте:
Создание WAR архива Spring Boot приложения и deploy на Apache Tomcat
Чтобы задеплоить написанное приложение на tomcat необходимо выполнить следующие действия:
Класс Application должен приобрести следующий вид:
В файл pom.xml дописываем <packaging>war</packaging> после тега version в начале файла.
Далее создаем war архив (View/Tool Windows/Maven Projects):
В проекте создалась папка target и в ней файл war.
Останавливаем проект и запускаем Apache Tomcat.
Заходим в Application List и деплоим наш файл, предварительно переименовав его, как вам удобно:
Сегодня я покажу Вам как создать java веб приложение используя возможности фреймворка Spring Boot. Будем писать и бекенд и фронтенд с нуля. Для тех, кто хотел начать изучать Spring, данная статья может послужить очень хорошим началом. В ней я даю ссылки на другие статьи где определенные технологии описаны более детально.
Тем, кто уже знаком со Spring, статья поможет собрать все знания воедино, закрепить их, и написать простое приложение в копилку к портфолио.
Для тех, кому лень читать: видео в конце страницы; код в описании к видео.
Технологии, которые мы будем использовать:
Создание простого Spring Boot приложения
Дальше нужно открыть проект в любом удобном java редакторе. В этой статье я использую intellij idea. Как я пишу в каждой статье: выбирайте такой редактор, который удобен именно Вам.
После вышеперечисленных шагов у Вас должен быть открыт проект с одним единственным классом SpringCrudApplication. Название этого класса спринг берет частично с названия самого проекта. Поэтому у Вас он может иметь другое название. Это не принципиально.
Структура Spring Boot приложения
Данный класс имеет main метод, который является точкой входа в приложение. Аннотация SpringBootApplication указывает что приложение будет запускаться как Spring Boot приложение. Она также указывает спрингу, что для всего что у нас есть в файле зависимостей pom.xml нужно подключить авто конфигурацию. Если Вам нужно кастомизировать конфигурацию под определенные зависимости, то автоконфигурацию можно легко отключить, указав в списке exclude внутри аннотации SpringBootApplication:
Все настройки приложение по умолчанию берет из файла application.properties. Чтобы указать спринг как ему получить доступ к базе данных, нужно добавить в данный файл путь к базе данных, имя пользователя и пароль с такими ключами:
Spring Boot возьмет вышеуказанные данные и на их основании сделает пул соединений (стандартный).
Теперь, приложение должно запускаться. По умолчанию оно использует порт 8080, который тоже можно поменять указав нужный в конфигурационном файле (application.properties).
Я создал простую страницу с приветствием:
Дальше, когда все приготовления с базой готовы, нужно написать слой доступа к базе данных. Создаем сперва класс отображения сущности. Если у нас таблица users_table нужно создать класс который будет ее отображением в java. Сначала создадим пакет entity, в который и поместим наш класс сущность. Назовем его Users. В данном классе создадим поля, которые есть в базе и навешаем на наш класс и поля аннотации java persistence: Table, Entity, Column, Id. Если для Вас эти термины новы, советую почитать статью по хибернейт и персистенс. Чтобы избежать написание геттеров, сеттеров, equals, hashCode, toString, я воспользуюсь аннотациями библиотеки Lombok.
В результате всех манипуляций, мой класс Users имеет вид:
Дальше на очереди JPA репозиторий. Подробнее о Spring Data JPA я писал раньше. Теперь, пришло время все это соединить в один проект.
Создадим пакет repository в который поместим интерфейс UsersRepository. Унаследуем этот интерфейс от JpaRepository указав в треугольных скобках нашу сущность с которой будет работать репозиторий и тип первичного ключа (Users, Integer). Предлагаю сразу добавить в репозиторий метод findByLogin. Чтобы можно было искать пользователя по логину. Напоминаю, что CRUD методы по работе с сущностью уже встроенны в JpaRepository и писать их самому не нужно. Такие методы как save(), saveAll(), delete(), findById() готовы к использованию. Использовать их мы будем в слое сервиса. Наш репозиторий выглядит следующим образом:
После работы с jdbc этот код выглядит как магия.
Именно в этот класс мы будем превращать нашу сущность юзер когда достанем данные из базы. Также этот класс будет нам служить трансфером между клиентом, контроллером и сервисом.
На очереди слой сервисов. Сначала создаем пакет service. В него добавляем интерфейс UsersService. Далее в интерфейсе добавляем методы которые нам нужны для работы:
В данном примере проверим чтобы объект UsersDto не был пустым и чтобы поле логин было заполнено. В идеале же еще нужно проверять чтобы емейл был в правильном формате. Для учебных целей я упустил все эти моменты, но, на реальных проектах, Вы должны стараться провалидировать входные данные по максимум перед тем как сохранять их в базу.
Я вынес валидацию в отдельный метод, чтобы было легче читать код:
После того как UsersDto пройдет валидацию, переконвертируем его в Users:
Для того, чтобы не писать весь код в одном классе я вынесу конвертацию из класса сервиса в другой класс. Назову его UsersConverter. В этот класс я и помещу метод fromUserDtoToUser. Предлагаю сразу написать конвертацию из UsersDto в Users. И, для демонстрации Вам еще одной фишки библиотеки Lombok я воспользусь встроенным в ломбок паттерном билдер. Для начала я добавлю в класс UsersDto аннотацию @Builder. Она реализовывает в данном классе паттерн билдер. Теперь я могу создавать объекты UsersDto через builder. Это достаточно популярный паттерн проектирования. Советую ознакомиться с ним.
Мой метод по конвертации из Users в UsersDto будет выглядеть так:
Если не нравиться паттерн builder можно делать по аналогии с методом fromUserDtoToUser.
Для того, чтобы спринг создал бин моего класса UsersConverter я навешу на него аннотацию @Component. Это позволит мне использовать внедрение зависимостей (dependency injection) и подлючить этот класс в мой класс DefaultUsersService используя Spring Dependency Injection.
Теперь, вернемся в наш класс DefaultUsersService и подключим к нему UsersRepository и UsersConverter. Я будут использовать внедрение зависимостей через конструктор. А Lombok поможет мне с конструктором. Для начала я объявляю переменные классов:
Мой компилятор ругается что нужно проинициализировать данные переменные используя конструктор. И правда: ведь мои переменные имеют final модификатор, что говорит о том что они должны быть проинициализированы. Компилятор предлагает инициализировать их в констукторе. Так я и сделаю. Только чтобы не писать его руками я воспользуюсь аннотацией @AllArgsConstructor из библиотеки ломбок. Заодно и навешаю на свой класс аннотацию @Service чтобы потом внедрить его в контроллер.
Дальше приступаю за оформление saveUser:
- вызываю validateUserDto для валидации входящих данных;
- конвертирую в юзера Users convertedUser = usersConverter.fromUserDtoToUser(usersDto);
- сохраняю в базу данных Users savedUser = usersRepository.save(convertedUser);
- конвертирую сохраненного юзера обратно в дто и возвращаю return usersConverter.fromUserToUserDto(savedUser);
В методе deleteUser я просто удаляю пользователя по айди:
Метод findAll похож на findByLogin с той лишь разницей что мы винимаем всех пользователей из базы и потом конвертируем их в список дто. Для обхода списка и конвертации я воспользовался стримами java. Но Вы может пользоваться простым циклом если сложно по началу разобраться со stream.
Наш класс DefaultUsersService после всех преобразований имеет такой вид:
На очереди слой контроллер. Создадим новый пакет controller в который поместим новый класс UsersController. Данный класс будет отвечать за обработку запросов по работе с сущностью User. Чтобы вызывать методы по созданию, удалению и выборке пользователей подключим в наш контроллер только что созданный UsersService таким же образом как мы подключали репозиторий и конвертор компонент: внедрение зависимостей через конструктор.
Чтобы наш класс стал контроллером простого названия мало. Нужно навешать на него аннотацию @RestController которая укажет спринг что данный класс предоставляет REST API.
В контроллере не должно содержаться никакой логики по работе с сущностями. Вся логика сосредоточена в сервисном слое. Поэтому, в контроллере мы просто вызываем методы из сервиса и перебрасываем ответы на клиент:
На этом разработка со стороны бекенда закончена. Нужно еще добавить юнит и интеграционных тестов но это уже тема другой статьи. Чтобы проверить работу приложения можно воспользоваться инструментом Postman. Он позволяет делать запросы на сервер и получать ответ.
Тестирование API используя Postman
Я просмотрел постманом все урлы моего приложения и убедился что они работают. На скрине выше пример запроса:
- выбираем метод запроса (POST);
- выбираем тело метода, тело метода будет иметь формат JSON;
- отправляем запрос и смотрим ответ.
Мне пришел ответ с моим сохраненным пользователем. У него появился айди, а это значит что он записался в базу данных и ему присвоился идентификатор. Для уверенности захожу в базу и проверяю все ли в порядке:
Сохраненный пользователь в базе данных
Теперь, когда я проверил что мой код работает так как я и ожидал, можно приступить к фронтенду.
Дальше нужно сделать запрос на сервер используя технологию AJAX (Asynchronous JavaScript and XML). Данная технология позволяет делать запросы без перезагрузки веб страницы. Это значительно приятней пользователям и смотрится современней.
Есть множество реализация AJAX на разных фреймворках. Но в данной статье мы разберем пример на Javascript не используя сторонние библиотеки и фреймворки.
После того как метод open вызван, нужно вызвать send метод, который может принимать тело запроса. Например наш запрос на создание пользователя будет выглядеть следующим образом:
После того как мы получим положительный ответ от нашего сервера (200 статус), то сможем отобразить полученные данные так как мы пожелаем.
Получилась не пара строк После цикла мы берем элемент у которого айди usersList и помещаем в него нашу сформированую таблицу. Только не забудьте в коде добавить сам элемент таблицы с нужным айди:
Чтобы функция loadUsers отработала ее нужно запустить. Просто вызовите ее после всех функций loadUsers();
Дальше добавим логику для создания нового пользователя. Для этого нам нужна простая html форма:
При нажатии на кнопку Create user будет работать функция createUser, которую мы еще должны сооздать:
Берем значения полей формы, формируем запрос JSON, делаем запрос на сервер. После этого вызываем функцию loadUsers чтобы наш вновь созданный пользователь отобразился на странице.
Подобно до сохранения делаем удаление пользователя. И также как и загрузка всех пользователей делаем поиск по логину.
Вот такой вот финальный файл получился после всех манипуляций:
Я советую вынести Javascript и CSS в отдельные файлы, чтобы Ваш код приобрел читабельный вид.
Наше простое веб приложение на Spring Boot готово.
Результат работы приложения
Статья получилась довольно обширной и местами сложной. В ней использовано очень много технологий которые сейчас популярны среди java разработчиков. Берете ее за основу, добавляете немного логики, больше функционала и помимо знаний, на выходе получаете отличный проект для своего портфолио.
Сейчас открыт набор на java mentor где мы по похожему сценарию только под моим руководством пишем немного усложненные варианты подобных проектов.
В дополнение к статье есть еще видео, где можно посмотреть разработку. В нем есть еще пункт с написанием юнит тестов с помощью mockito. Но этот момент я оставил для следующих статтей.
Читайте также: