Создание REST приложения с использованием Spring
HTML-код
- Опубликовано: 23 апр 2018
- В данном видео мы создадим REST приложение с использованием технологий:
Java,
Spring (Data, Boot),
MySQL
Maven,
Lombok
Ссылка на исходный код проекта:
github.com/proselytear/custom...
Наконец-то! Как же долго я ждал нового видео на этом канале! Надеюсь видео подобного формата будут выходить чаще!
Oleg Shentsev постараюсь выкладывать немного чаще )
Большое спасибо, ты лучший !
Планируются ли еще видео в ближайшем времени ??
Спасибо. Начал путь в Spring с вашего видеотуториала!
Вы помогаете нам развиваться! Спасибо!
Ого, Евгений. Давно вас не было! Вашы видео и ваш сайт - это большой вклад в русское программирование. Спасибо вам.
Дима Мухин спасибо за отзыв
Огромная благодарность что весь код пишется, а не копипастится из других проектов! Так намного понятнее что для чего.
Мужик -- большое человеческое спасибо за то, что ты не только пишешь код, но и объясняешь что он делает. Хоть что-то в голове откладывается.
Спасибо за отзыв, Юрий :)
Огромное спасибо за урок - очень круто все разложено!
Спасибо за урок!!! Очень доступно объясняете!!!
Спасибо за отзыв )
Дядь, спасибо за видео! С корешем решили в 30 лет стать разрабами, твои видео очень ценны)
и как успехи?
@@Mastervmf Снова на мойке работают оба
@@user-wh8ye3id7s пхахах
Огромное спасибо за видео по REST.
Ruslan Zinovyev спасибо за отзыв )
Великолепно! Очень полезно, лучшие видео по spring в СНГ. И объясняете даже лучше чем в видео о CRUID. Хотя и там достаточно хорошо объясняли. Не согласен с людьми, которые бубнят, что вы отправляете к документации. Я считаю, пары информативных слов в стиле "эта зависимость поможет нам автоматически генерировать геттеры, сеттеры toString() и красиво логировать" это идеальное краткое содержание. Спасибо ещё раз, надеюсь ещё будут видео по Spring, Maven, ORM и тп
Спасибо за отзыв, Евгений.
Спасибо, мужик. Прям очень хорошо рассказал. Помогло в работе, спасиб)))
Спасибо за отзыв :)
Отлично! Спасибо!
Спасибо за видео! Только, ПОЖАЛУЙСТА, делайте шрифт крупнее или уменьшите разрешение экрана. Смотреть на ноутбуке 15' крайне неудобно. Пожалейте наши глаза)
Sergey Gasak спасибо за отзыв. По поводу шрифта - уже говорили - учту на будущее )
@AniBot ++)
Спасибо за видео!
Спасибо Евгений! Уже если честно не думал что будут новые видео. Да и на сайте статьи перестали выходить.
Alex Snowden теперь постараюсь выкладывать чаще. Спасибо за отзыв
Спасибо! Добрейшего тебе мира!
Спасибо!
Большое спасибо за видео!
спасибо, конечно если бы почаще свежих видео))
*СПАСИБО ВАМ БОЛЬШОЕ!!!!!*
СПАСИБО!!!!!!!
Огромное вам спасибо
Большое спасибо
Спасибо
У меня *JpaRepository* реализует метод *getOne(Long),* а не _findOne(Long),_ как у Вас...
И *deleteById(Long),* вместо _delete(Long),_ соответственно.
Я ставил зависимость *spring-boot-starter ver.:2.0.2.RELEASE*
Правда, в этом случае - ошибка при компиляции, связанная с логированием - в аpplication.properties надо прописать что-то вроде: *logging.level.com.mvictorl = INFO* (вместо logging.level. = INFO)
Можно небольшой комментарий по поводу logging.level.com.mvictorl = INFO? Как понять, что здесь писать надо?
@@user-fr2dw3qd4v
На сколько я помню, *logging.level.* - это имя свойства, т.е. уровень логирования, а *com.mvictorl* - это пространство имён, к которому этот уровень применяется, он у каждого приложения свой (по-моему это ArtifactId при создании приложения). Ну, и *INFO* - это значение уровня логирования, то, что будет в логах (ERROR, WARNING, INFO и т.д.)
howtodoinjava.com/spring-boot2/logging/logging-application-properties/
Я только начинаю учить спринг и понял всё процентов на 70%
Первое, что я сказал по завершению видео: ах*еть
Круто, спасибо!
Евгений топ! Спасибо!
Спасибо за отзыв!
Евгений хорошее обучающее видео.Узнал что-то новенького из вашего видео. Сейчас как раз надо написать приложение наподобие,только чуть посложнее.
Может что-то сможете подсказать - нужно создать функционал уведомлений о предстоящем мероприятии по наступлению
даты события.Сама логика понятна - нужно сравнивать будет дату мероприятия с текущей датой,и при положительном результате выдавать уведомления.А вот что имеется в виду - функционал уведомлений???
Замечательное видео. Евгений, не могли бы вы осветить тему авторизации и разграничения доступа в REST.
Спасибо. Эта тема заслуживает отдельного видео - планирую записать в скором времени.
ждем
Отличное видео, на многое открыло глаза)) Вот только не понял как вы связывали созданные скрипты БД с Database ???
Эта логика ложится на liquibase.
Т.е. конфигурируем, запускаем, а liquibase делает всю работу
Спасибо за проделанную работу!!
Но есть вопрос: зачем отдавать клиенту 404 если данные в базе не найдены по id.
404 это же запрос несуществующего роута??
Капитан!!!
Добрый день!
Видео очень классное, есть вопрос такой, на понимание, не совсем понял принцип работы, может он покажется простым и глупым, но все же:). Занимаюсь изучением фреймворка Spring. В контроллере(у вас это CustomerRestController) инициализируется интерфейс сервиса(CustomerService) как Автовайред, а не ссылка на класс реализующий методы итерфейса(CustomerServiceImpl). Я правильно понял , что это логика Spring такая, то есть Spring находит класс где есть имплементация методов CustomerService с бизнес-логикой, и при обращении к методам CustomerService из контроллера , находит имеющуюся в CustomerServiceImpl реализацию методов в контексте спринга?
Добрый день, Алмаз. Да, все верно, именно так.
Это и есть базовый функционал спринга. Я бы рекомендовал крайне детально изучить этот механизм.
proselyte.net/tutorials/spring-tutorial-full-version/dependency-injection/
proselyte.net/tutorials/spring-tutorial-full-version/autowiring/
Надеюсь, ответ будет полезен.
@@EugeneSuleimanov Евгений, спасибо за ответ!
если вас заинтересует было бы отличной темой для урока тестирование спринг прилолжений как это
Отличное видео!... Прозвучала фраза, что используется томкат, но в самом видео про него вроде как ничего нет... его spring-boot подтягивает или как?
Владимир Баранов да, в помнике есть зависимость стартера томката. Спасибо за отзыв)
Спасибо, очень хороший урок. Евгений пропала связь с вами в Skype.
Было бы хорошо в последующих видео увеличить шрифты в IDE-шке на время записи, поскольку человеку со слабым зрением оочень сложно разобрать код, а огромное количество места в кадре и так остается незадействованным.
Таким образом хорошее видео станет доступным для большего количества людей)
Спасибо.
Да, уже видел этот момент - в будущем обязательно учту при записи, спасибо
дошел до последнего но так и не понял (видео норм ток лучше бы побольше разъяснений про аннтации типо @REquestBody,PathVariable и прочее может remastered Создание REST приложения с использованием Spring ?)
Запилите видео, как теперь правильно запилить клиент для всего этого на спринге, пожалуйста. А то у меня только куча говнокода выходит)
Клиент на спринге, как это?
@@user-jf2ic3up1k не бери в голову. Я пьяная наверное была, когда этот коммент писала)
Спасибо за видео. Пришлось немного поплясать с бубном, но приложение в итоге заработало, правда с ломбоком не разобрался - плагин почему-то постоянно отваливается и idea не понимает что за log я хочу.
В _BaseEntity_ класс должен быть *_public_* или *_abstract_* ?
И какая разница между *_@MappedSuperclass_* и *_@Inheritance_* ?
Большое спасибо за видео! А вы не подскажете, почему при инициализации бд, инициализируется только схема, а данные в бд не записываются?
Спасибо за отзыв.
Это странно, т.е. есть чендж сет, в файле. В нем указано, что мы вставляем данные. Приложение запускается без ошибок, но данные на записаны?
@@EugeneSuleimanov да, у меня есть два дампа базы данных postgresql: схема и данные. Все таблицы из схемы создаются, но не заполняются данными.
Всем у кого возникают вопросы во время просмотра видео. Рекомендую вдумчиво и неспеша изучить руководство по спринг от автора данного видео - proselyte.net/tutorials/spring-tutorial-full-version/introduction/ а так же - мой вам совет, смотрите видео с паузами, возвращайтесь к просмотренному, делайте выписки и гуглите, что непонятно по аннотациям или другим попутным вопросам. Таким образом, все постигается и картина становится ясной.
Большое спасибо за видео. Подскажите пожалуйста, почему метод updateCustomer идентичен методу saveCustomer?
Спасибо за отзыв )
Здесь идентичен, но логика может меняться. Поэтому используем 2 отдельных метода
Спасибо за урок. То, что нужно. Но у меня проблемка: на 17:19 строка return customerRepository.findOne(id); выдаёт ошибку - может возрващаться null, и подсказка синтаксиса пишет, что customerRepository.findOne(id) возрващает НЕ Customer, а Optional. Не очень понимаю, почему у вас не так - возможно какая-то версия спринга отличается... И как решать эту проблему именно правильно тоже не очень понимаю, ибо не хочу я тут видеть Optional, мне нормальный объект нужен :) У меня в проекте Java 1.8, spring-data-jpa 2.1.10RELEASE, spring 5.1.10.RELEASE. UPD: Нашёл на просторах инета такое решение: .findById(id).orElse(null);
Спасибо за отзыв! Да, это верное решение для работы с Optional
Отличный урок! Я только с update не понял, мы на вход в запросе никакого id не даем, чем оно отличается от добавления кастомера обычным POST, кого мы апдейтим?
Спасибо за отзыв, Филипп. В update мы передаём весь объект вместе с id. Spring Data сам понимает, что сущность уже есть в БД и изменяет уже существующую, а не создаёт новую. Примерно, так.
Спасибо, разъяснили.
@@EugeneSuleimanov Спасибо, за обьяснение а , UriComponentsBuilder componentsBuilder в методе Update зачем , он ведь все равно не используеться?
Вы поменяли комп*ютер?
Спасибо за видео, но очень мелко, тяжело разобрать информацию, особенно когда с Поустмэном работаете
Denis N спасибо за отзыв. Учту при создании новых видео. Постараюсь делать более читабельно.
@PutMapping, для чего вы передали UriComponentsBuilder в качестве параметра? Вы же его не используете. В чем суть?
Здесь это избыточно и можно было обойтись без него. Просто в демонстрационных целях, но, вероятнее всего, не стоило этого делать - вводит в заблуждение.
В baseEntity описываются общие свойства которые мы можем унаследовать для таблицы, мы так делаем чтобы проще было управлять таблицей и не загромождать класс Customer или для чего то ещё?
Да, верно
Здравствуйте. За видео огромный респект. Приложение запустилось хоть и не с первого раза, но у меня возник вопрос по методу updateCustomer. Проверяя его методом PUT в Posman у меня пользователь не обновляется, а записывается еще один новый с измененными полями. Выдает метод GET. Да и в логике метода я не вижу ни где удаления старого customera. Может я что то упустил?
Добрый вечер.
Спасибо за отзыв. По поводу вашего вопроса - передаёте ли вы id кастомера в теле запроса?
В идеале - скиньте, пожалуйста, cURL
Можно ли использовать одну аннотацию _lombok_ *@Data* вместо *@Getter, @Setter, @ToString* и *@EqualsAndHashCode* в Entity класах ?
Нужно ) Это только для видео, чтобы было максимально понятно, что здесь происходит
Спасибо, очень хороший урок. Но ви добавили гедер и билдер, но так и не исппользовали их, можно еще маленьеий урок с более сложними запросами и использованием гедера и билдера.
Sviatoslav Naida не могли бы вы уточнить - тогда смогу в будущем записать такое видео
Eugene Suleimanov, я имел ввиду запросы с добавдение кастомной информации в гедер и зачем нам билдер как его использовать в реальных условиях и возможно что то еще что нужно испоользовать в сложных запросах. Спасибо большое.
И как кеш использовать правильно
добрый день. а в мире java и в частности spring, для версионирования db, миграции использовать не принято?
Дмитрий Лучкин добрый день.
Да, конечно. В видео сказано, что в реальном проекте мы бы использовали миграции liquibase, flyware и т.д.
Прошу прощения за назойливость, но не совсем понятно зачем нам нужен параметр builder в методе updateCustomer. В самом методе он нигде не задействован. Это первый вопрос. И второй вопрос. Нужно ли выносить создание HttpHeadrs на уровень класса, или данное дублирование обусловлено созданием своего Хэдэра при каждом запросе. СПС
Denis N в данном случае он не нужен. По поводу хедера - все верно - мы контролируем создание хедера при каждом запросе.
спасибо
Подскажите пжл, выносить работу с ID в отдельный класс необходимо для будущего расширения (при необходимости)?
Denis N это обычная практика. Практически, во всех проектах, где я работал, применялся подобный подход.
спасибо за ответ.
Не совсем понял в конце по поводу использования базы данных "в реальном приложении"...
39:58
Есть специальные средства для миграции БД. Они дают возможность отслеживать что, когда и кем было изменено в БД.
Eugene Suleimanov
Можно названия, чтобы почитать хотя бы? Спасибо!
www.liquibase.org/ и flywaydb.org/ - это наиболее популярные
Eugene Suleimanov
Спасибо большое!
В чем суть деления на service и на repository? Если делать методы в repository что будет? и на что это влияет?
Обычно, репо отвечает за работу с БД, а сервис - за бизнес логику приложения.
@@EugeneSuleimanov спасибо. Так строится вся ПО?
Хоспаде, откуда такая любовь к спринг бут? Без бута не справился бы?
Без boot нужно думать и быть умным, а я так - погулять вышел…
У меня почему то log красным подсвечивает и IDE не видит ее несмотря на то что все зависимости в pom прописаны и аннотация @Slf4j на месте.
Если по факту приложение запускается, то попробуйте установить плагин Lombok в IDEA - это должно решить проблему.
была та же ошибка с логированием, плагин так и не решил проблему, проект запускается только в postman ничего не приходит
Было такое же...
Установка плагина Lombok (с _предлагаемой после установки_ перезагрузкой IDEA) решил проблему!
Откройте "Файл"> "Настройки"> "Плагины".
Нажмите "Обзор репозиториев"...
Поиск плагина Lombok
Нажмите "Установить плагин".
Перезапустить IntelliJ IDEA
Евгений, почему забросили канал и сайт ? :(
Тяжела и не казиста жизнь тех.лида- программиста :). Тотальная нехватка времени. Сейчас по-немноу записываю 2 курса - многопоточность + Spring 5, но когда получится выкатить - не знаю. Постараюсь весной выложить.
Зачем нужен интерфейс CustomerService? Можно же сразу через класс сделать
Это потуги на SOLID. В данном случае и без него отработает, но по стандарту делаем через интерфейс.
@@EugeneSuleimanov понятно, спасибо.
Ждём камбек на ютуб)
извини, я не понял за чем нужно логирование, можеш подсказать где я могу почитать об этом?
Для мониторинга приложения и для поиска причин ошибок, если такие будут
Аннтации @Valid - где её взять?
При import javax.validation.Valid;
не может найти validation
Автор, помоги плиз)
это в CustomerRestControllerV1 в методе saveCustomer
я уже нашёл ответ :D
добавьте в pom.xml зависимость
org.springframework.boot
spring-boot-starter-validation
Не успел :)
Не совсем корректно раотают методы с ID , и некорректно обработаны експепшены. В случае невалидного айди вылетает внутрення ошибка java.util.NoSuchElementException: No value present. Все проверки на null не валидны
Я обязательно перепроверю работу метода получения по id. При необходимости, внесу изменения на гитхаб репо и продублирую ссылку. Спасибо за сообщение.
@@EugeneSuleimanov Сорри я не указал что на монге пробовал запускать, для того что бы вылетала ошибка 404 вместо 501 дописл в сервисном методе return customerRepository.findById(id).orElseThrow(NotFoundException::new) и свой эксепшен
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Invalid ID")
public class NotFoundException extends RuntimeException {
бесплатная идея не работает со спрингом? а у вас платная идея?
Насколько я знаю, там нет spring initializer, но, не уверен, крайне давно не сталкивался с community edition. Т.е. работать со спрингом сможете, но нет встроенного инициализатора прокта.
А зачем логика в рест-контроллере описана?
для это же сервисы существуют
Проверку на null и пустой список вряд ли можно назвать логикой. Но, это спорный вопрос, конечно же
можно не писать updateCustomer а просто update тк Customer у нас уже в название класса
А как то вместо if можно Optional прикрутить?
Конечно
@@EugeneSuleimanov А как если не секрет?))
сначало бился изза mysql 8.0, забил на него снес поставил 5.6, вроде debug смотрю restController отдает лист, но в postman приходит только статус
c git скачал проект, те же самые ошибки и с логирование и пустым response ((((
Java какая?..
1.8
Samat Zhakin
А в свойствах проекта?
тоже
Вечером попробую - отпишусь...
Сложно без объяснений. Здесь добавим эту аннотацию, там ту, здесь билдер, а нет не надо или надо, нет не надо.
А откуда что берется - сам решай. Это ж не мастер-класс, а урок. Такое чувство, что за автором гонятся, прям такая спешка.
Видео про то как парень пишет код. Обучения и объяснений тут нет.
Видео может и очень полезное, но не стал смотреть из-за очень уж мелкого разрешения экрана. Так это я ещё на 15,6", а представьте кого-то со смартфоном)
Вы имеете в виду шрифт или низкое разрешение?
@@EugeneSuleimanov Высокое разрешение экрана, от этого текст в видео тяжело рассмотреть. Не в обиду конечно, но глаза уже полезли на лоб за первые 20 секунд просмотра(
@@EugeneSuleimanov Я часто смотрю подобные видео со смартфона, когда в дороге нахожусь, там бы точно ничего не было бы видно. Поэтому советую ставить разрешение поменьше хотя бы, когда снимаете видео ;)
почему у меня записываются нулы???
Значит не приходят данные и по умолчанию записываются null
Майн риспектунг
Спасибо за отзыв!
@@EugeneSuleimanov Ваши видео правда помогли мне глубже понять то, как работать со спринг, поэтому я правда вам очень благодарен.
я вот не понимаю, зачем нам репозиторий с методами которое мы реализуем, так при этом ещё создавать сервис с методами, зачем это все?
Обычно, репозиторий отвечает за "атомарные" операции с БД. А сервис - это наша бизнес-логика, вычисления и т.д. Хоть в данном приложении такой сложной логики и нет, мы должны оставить возможность для ее простой реализации
@@EugeneSuleimanov Спасибо
странно, что столько положительных отзывов, автор толком ни чего не объясняет, просто сухо комментирует не объясняя как это работает и для чего. самый главный минус это то что 35 минут пишет код, и только в конце запускает показывая результат, было бы гораздо лучше если написал немного продемонстрировал, добавил еще - показал еще. короче зря потратил 40 минут, есть гораздо лучше туториалы
можешь подсказать туториалы по лучше? Назву или ссылку, как удобнее
Ничерта не получилось (( не коннектится к БД хоть ты тресни. А за видео спасибо
Какие логи ошибки? И спасибо за отзыв!
@@EugeneSuleimanov Unable to create initial connections of pool. Скрин: yadi.sk/i/IurEtQRFgFdMjA
классное видео
но работает криво и безрезультатно, даже ваш проект (((
это демотиватор, ниче не понятно, знакомое слово Лобок
Спасибо