diff --git a/.gitignore b/.gitignore index 73e6d9e3dd11..b4860155a096 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,4 @@ out target *.iml log -*.patch - - +*.patch \ No newline at end of file diff --git a/README.md b/README.md index 4e07fe385b23..7eba7e8652f5 100644 --- a/README.md +++ b/README.md @@ -1,251 +1,148 @@ -[Java Enterprise Online Project](https://javaops.ru/view/topjava) +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/bee16f3145654047a0505c62aeefd8a2)](https://app.codacy.com/gh/JavaWebinar/topjava/dashboard) +Java Enterprise Online Project =============================== -Разработка полнофункционального Spring/JPA Enterprise приложения c авторизацией и правами доступа на основе ролей с использованием наиболее популярных инструментов и технологий Java: Maven, Spring MVC, Security, JPA(Hibernate), REST(Jackson), Bootstrap (css,js), DataTables, jQuery + plugins, Java 8 Stream and Time API и хранением в базах данных Postgresql и HSQLDB. -![topjava_structure](https://javaops.ru/static/images/projects/top-scheme.jpg) - - Когда вы слышите что-то, вы забываете это. - Когда вы видите что-то, вы запоминаете это. - Но только когда вы начинаете делать это, - вы начинаете понимать это - - Старинная китайская поговорка - -## Описание и план проекта -### Демо разрабатываемого приложения -### [Изменения проекта (Release Notes)](ReleaseNotes.md) -### Требования к участникам, Wiki -### Составление резюме, подготовка к интервью, поиск работы - -Обновленное вводное занятие (обязательно смотреть все видео) -=============== -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Вступление, история, команда, источники](doc/video1.md) - -## Обзор наиболее востребованных технологий, которые будут изучаться на курсе TopJava -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2.1. [Часть 1: инфраструктура](doc/video2.1.md) - -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2.2. [Часть 2: frameworks Spring, ORM](doc/video2.2.md) - -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2.3. [Часть 3: тренды](doc/video2.3.md) - -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2.3. [Часть 4: обзор разрабатываемого приложения](doc/video2.4.md) - -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. [Рекомендуемые подходы к обучению на курсе](doc/video3.md) - -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Структура приложения (многоуровневая архитектура)](doc/video4.md) -### [Демо приложения](http://javaops-demo.ru/topjava) - -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 5. [Системы управления версиями. Git](doc/video5-vcs-git.md) - -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 6. Работа с проектом (выполнять инструкции) -- **ВНИМАНИЕ: выбирайте для проекта простой пусть без пробелов и русских букв, например, `c:\projects\topjava\` (Windows). Иначе впоследствии будут проблемы** -- **Плагин Git Intergation уже не требуется, а вкладку `Version control` в IDEA переименовали в `Git`** - -Для переключения режима отображения изменений из вкладки `Commit` в `Git: Local Changes` нужно переключить `Settings/Preferences | Version Control | Commit | Use non-modal commit interface` или в контекстном меню вкладки `Commit`: - -![image](https://user-images.githubusercontent.com/13649199/105491518-72d8f300-5cc7-11eb-8b79-c46382562deb.png) ![image](https://user-images.githubusercontent.com/13649199/105488663-05c35e80-5cc3-11eb-962e-30f403d623e8.png) - -### Патч [prepare_to_HW0.patch](https://drive.google.com/file/d/1LNPpu9OkuCpfpD8ZJHO-o0vwu49p2i5M) (скачать и положить в каталог вашего проекта) - -> Проект постоянно улучшается, поэтому видео иногда отличается от кода проекта. Изменения указываю после видео: -> - переименовал класс `UserMealWithExceed` и его поле `exceed` в `UserMealWithExcess.excess` -> - в `UserMeals/UserMealWithExcess` поля изменились на `private` -> - обновил данные `UserMealsUtil.meals` и переименовал некоторые переменные, поля и методы -> - добавил `UserMealWithExcess.toString()` и метод для выполнения _Optional домашнего задания_ -> - метод фильтрации в `TimeUtil` переименовал в `isBetweenHalfOpen` (также изменилась логика сравнения: `startTime` включается в интервал, а `endTime` - не включается) - -### GitHub поменял политику: теперь пушить нужно через токен. IDEA предложит его сгенерировать при пуше, или можно [создать токен в настройках](https://www.jetbrains.com/help/idea/github.html#register-account) -- [Способы авторизации в GitHub](https://topjava.ru/blog/vvedeniye-v-git-github-ustanovka-i-nastroyka#6) +Наиболее востребованные технологии /инструменты / фреймворки Java Enterprise: +Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + plugins. + +- [Вступительное занятие](https://github.com/JavaOPs/topjava) +- [Описание и план проекта](https://github.com/JavaOPs/topjava/blob/master/description.md) +- [Wiki](https://github.com/JavaOPs/topjava/wiki) +- [Wiki Git](https://github.com/JavaOPs/topjava/wiki/Git) +- [Wiki IDEA](https://github.com/JavaOPs/topjava/wiki/IDEA) +- [Демо разрабатываемого приложения](http://javaops-demo.ru/topjava) + +### 25.01: Старт проекта +- Начало проверки [вступительного задания HW0](https://github.com/JavaOPs/topjava#-Домашнее-задание-hw0) + +#### 30.01 Дедлайн на сдачу HW0 +### 01.02: 1-е занятие +- Разбор домашнего задания вступительного занятия (вместе с Optional) +- Обзор используемых в проекте технологий. Интеграция ПО +- Maven +- WAR. Веб-контейнер Tomcat. Сервлеты +- Логирование +- Уровни и зависимости логгирования. JMX +- Домашнее задание 1-го занятия (HW1 + Optional) + +#### 08.02 Дедлайн подачи заявки на [дипломную программу](https://javaops.ru/view/register/diploma) +### 08.02: 2-е занятие +- Разбор домашнего задания HW1 + Optional +- Библиотека vs Фреймворк. Стандартные библиотеки Apache Commons, Guava +- Слои приложения. Создание каркаса приложения +- Обзор Spring Framework. Spring Context +- Пояснения к HW2. Обработка Autowired +- Домашнее задание (HW2 + Optional) + +### 15.02: 3-е занятие +- Разбор домашнего задания HW2 + Optional +- Жизненный цикл Spring контекста +- Тестирование через JUnit +- Spring Test +- Базы данных. Обзор NoSQL и Java persistence solution без ORM +- Установка PostgreSQL. Docker +- Настройка Database в IDEA +- Скрипты инициализации базы. Spring Jdbc Template +- Тестирование UserService через AssertJ +- Логирование тестов +- Домашнее задание (HW3 + Optional) + +### 22.02: 4-е занятие +- Разбор домашнего задания HW3 + Optional +- Методы улучшения качества кода +- Spring: инициализация и популирование DB +- Подмена контекста при тестировании +- ORM. Hibernate. JPA +- Поддержка HSQLDB +- Домашнее задание (HW4 + Optional) +#### Начало выполнения [выпускного проекта](https://github.com/JavaOPs/topjava/blob/master/graduation.md) + +### 29.02: 5-е занятие +- Обзор JDK 9/17. Миграция Topjava с 1.8 на 17 +- Разбор вопросов +- Разбор домашнего задания HW4 + Optional +- Транзакции +- Профили Maven и Spring +- Пул коннектов +- Spring Data JPA +- Spring кэш +- Домашнее задание (HW5 + Optional) + +### 07.03: 6-е занятие +- Разбор домашнего задания HW5 + Optional +- Кэш Hibernate +- Spring Web +- JSP, JSTL, internationalization +- Динамическое изменение профиля при запуске +- Конфигурирование Tomcat через maven plugin. Jndi-lookup +- Spring Web MVC +- Spring Internationalization +- Домашнее задание (HW6 + Optional) + +#### Большое ДЗ + выпускной проект + начинаем [курс BootJava](https://javaops.ru/view/bootjava) + подтягиваем "хвосты". + +### 21.03: 7-е занятие +- Разбор домашнего задания HW6 + Optional +- Автогенерация DDL по модели +- Тестирование Spring MVC +- Миграция на JUnit 5 +- Принципы REST. REST контроллеры +- Тестирование REST контроллеров. Jackson +- jackson-datatype-hibernate. Тестирование через матчеры +- Тестирование через SoapUi. UTF-8 +- Домашнее задание (HW7 + Optional) + +### 28.03: 8-е занятие +- Разбор домашнего задания HW7 + Optional +- WebJars. jQuery и JavaScript frameworks +- Bootstrap +- AJAX. Datatables. jQuery +- jQuery notifications plugin +- Добавление Spring Security +- Домашнее задание (HW8 + Optional) + +### 04.04: 9-е занятие +- Разбор домашнего задания HW8 + Optional +- Spring Binding +- Spring Validation +- Перевод DataTables на Ajax +- Форма login / logout +- Реализация собственного провайдера авторицазии +- Принцип работы Spring Security. Проксирование +- Spring Security Test +- Cookie. Session +- Домашнее задание (HW9 + Optional) + +### 11.04: 10-е занятие +- Разбор домашнего задания HW10 + Optional +- Кастомизация JSON (@JsonView) и валидации (groups) +- Рефакторинг: jQuery конверторы и группы валидации по умолчанию +- Spring Security Taglib. Method Security Expressions +- Интерсепторы. Редактирование профиля. JSP tag files +- Форма регистрации +- Обработка исключений в Spring +- Encoding password +- Миграция на Spring 5 +- Защита от межсайтовой подделки запросов (CSRF) +- Домашнее задание (HW10) + +### 18.04: 11-е занятие +- Разбор домашнего задания HW10 + Optional +- Локализация datatables, ошибок валидации +- Защита от XSS (Cross Site Scripting) +- Обработка ошибок 404 (NotFound) +- Доступ к AuthorizedUser +- Ограничение модификации пользователей +- Деплой приложения [на собственный выделенный сервер](https://github.com/JavaOPs/startup) +- Домашнее задание (HW11): сокрытия полей в Swagger +- Составление резюме. Собеседование. Разработка ПО. Возможные доработки приложения -## Инструкция по шагам (из видео): -- Установить ПО (Git, JDK8, IntelliJ IDEA, Maven) -- Создать аккаунт на GitHub -- Сделать Fork **ЭТОГО** проекта (https://github.com/JavaOPs/topjava) -- Сделать локальный репозиторий проекта: -
git clone https://github.com/[Ваш аккаунт]/topjava.git- -> Вместо Fork можно сделать [клонирование проекта](https://github.com/JavaOPs/topjava/wiki/Git#user-content-Клонирование-проекта): он не будет привязан к исходному https://github.com/JavaOPs/topjava и у него не будет истории. - -- Открыть и настроить проект в IDEA - - Выставить кодировку UTF-8 в консоли - - Поставить кодировку UTF-8 - - Опционально: поменять шрифт по умолчанию на DejaVu или на **новый [JetBrains Mono](https://habr.com/ru/company/jugru/news/t/484134/)** -- По ходу видео сделать `Apply Patch...` скачанного патча `Prepare_to_HW0.patch` -- Закоммитить и запушить изменения (`commit` + `push`) -- Сделать ветку домашнего задания -- Выполнить задание и залить на GitHub (`commit` + `push`) -- Переключиться в основную ветку проекта `master`. - -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 7. [Maven](https://drive.google.com/file/d/1qEJTwv9FNUQjx-y9MSydH01xaAne0-hu) -- [Как установить Maven 3 на Ubuntu или Windows](https://devcolibri.com/как-установить-maven-3-на-ubuntu-или-windows/) -- [Руководство по Maven](https://topjava.ru/blog/apache-maven-osnovy-1) -- Wiki: [Apache Maven](https://ru.wikipedia.org/wiki/Apache_Maven) -- [The Central Repository](http://search.maven.org) -- Дополнительно: - - [Мой Wiki по Maven](https://github.com/JavaOPs/topjava/wiki/Maven) - - [Основы Maven](https://www.youtube.com/watch?v=0uwMKktzixU) - - JavaRush: [Основы Maven](https://javarush.ru/groups/posts/2523-chastjh-4osnovih-maven) - - Инструмент сборки проектов [Maven](https://www.examclouds.com/ru/java/java-core-russian/lesson20) - - [Maven Getting Started Guide](https://maven.apache.org/guides/getting-started/index.html) - - [Видео: Maven vs Gradle vs SBT (Архипов, Борисов, Садогурский)](https://www.youtube.com/watch?v=21qdRgFsTy0) - - [Build Lifecycle](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) - - [Dependency Mechanism](http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html) - -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 8. [Как правильно относиться к техзаданию (ТЗ). Полуоткрытый интервал.](https://drive.google.com/file/d/1BpTzjNFjS0TSekCyt_xvt6YoLvuw5KTZ) -- [Типы промежутков](https://ru.wikipedia.org/wiki/Промежуток_(математика)) - -## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Домашнее задание HW0 - -### ВНИМАНИЕ: НЕ НАДО в репозиторий делать Pull Request со своими решениями! См. видео выше ("Работа с проектом") - -Реализовать метод `UserMealsUtil.filteredByCycles` через циклы (`forEach`): -- должны возвращаться только записи между `startTime` и `endTime` -- поле `UserMealWithExcess.excess` должно показывать, превышает ли сумма калорий за весь день значение `caloriesPerDay` - -Т. е. `UserMealWithExcess` - это запись одной еды, но поле `excess` будет одинаково для всех записей за этот день. - -> - Проверьте результат выполнения ДЗ (можно проверить логику в [http://javaops-demo.ru/topjava](http://javaops-demo.ru/topjava), список еды) -> - Оцените Time complexity алгоритма. Если она больше O(N), например O(N*N) или N*log(N), сделайте O(N). -> **Внимание: внимательно прочитайте про O(N). O - это любой коэффициент, 2*N это тоже O(N).** - -- Java 8 Date and Time API -- Алгоритмы и структуры данных для начинающих: сложность алгоритмов -- [Сложность алгоритмов и Big O Notation](https://threadreaderapp.com/thread/1470666237286010881) -- [Головач: сложность алгоритмов в теме коллекций](https://www.youtube.com/watch?v=Ek9ijOiplNE&feature=youtu.be&t=778) -- Time complexity -- Временная сложность алгоритма -- Вычислительная сложность - -#### ВНИМАНИЕ: варианты Optional делайте в одной ветке в разных методах `UserMealsUtil`. Проще делать, проще проверять - -### Optional (Java 8 Stream API) -``` -Реализовать метод `UserMealsUtil.filteredByStreams` через Java 8 Stream API. -``` -- Видео: Доступно о Java 8 Lambda -- Java 8: Lambda выражения -- Java 8: Потоки -- Pуководство по Java 8 Stream -- [Полное руководство по Java 8 Stream API в картинках и примерах](https://annimon.com/article/2778) -- [7 способов использовать groupingBy в Stream API](https://habrahabr.ru/post/348536) -- Лямбда-выражения в Java 8 -- A Guide to Java 8 -- Шпаргалка Java Stream API -- Алексей Владыкин: Элементы функционального программирования в Java -- Yakov Fain о новом в Java 8 -- stream.map vs forEach` - - без циклов по другим коллекциям/массивам (к ним также относим методы коллекций `addAll()/removeAll()`) -- через Stream API за 1 проход по исходному списку `meals.stream()` - - нельзя использовать внешние коллекции, не являющиеся частью коллектора - - возможно дополнительные проходы по частям списка, при этом превышение должно считаться один раз для всего подсписка. Те например нельзя разбить список на на 2 подсписка с четными и нечетными датами и затем их объединить, с подсчетом превышения для каждого элемента. - -Временная сложность реализации должна быть O(N) (обратите внимание на п. 13 замечаний) -Решение должно быть рабочим в общем случае (должно работать в приложении с многими пользователями, не только при запуске `main`) -Нельзя 2 раза проходить по исходному списку (в том числе по его отфильтрованной или преобразованной копии) - -Ресурсы: -- [Baeldung: Custom Collectors](https://www.baeldung.com/java-8-collectors#Custom) -- [Руководство по Java 8 Stream API: Collector](https://annimon.com/article/2778#collector) -- [Хватит писать циклы! Топ-10 лучших методов для работы с коллекциями из Java 8](https://javarush.ru/groups/posts/524-khvatit-pisatjh-ciklih-top-10-luchshikh-metodov-dlja-rabotih-s-kollekcijami-iz-java8) -- [Понять Java Stream API](https://vc.ru/u/604567-yerlan-akzhanov/194409-ponyat-java-stream-api) - -### Замечания по использованию Stream API: -- Когда встречаешь что-то непривычное, приходится перестраивать мозги. Например, переход с процедурного на ООП-программирование дается непросто. Те, кто не знает шаблонов (и не хотят учить), также их встречают плохо. Хорошая новость в том, что если это принять и начать использовать, то начинаешь получать от этого удовольствие. И тут главное не впасть в другую крайность: - - [Используйте Stream API проще (или не используйте вообще)](https://habrahabr.ru/post/337350/) -- Если вас беспокоит производительность стримов, обязательно прочитайте про оптимизацию - - ["Что? Где? Когда?"](http://optimization.guide/intro.html) - - [Перформанс: что в имени тебе моём?](https://habrahabr.ru/company/jugru/blog/338732/) - - [Performance это праздник](https://habrahabr.ru/post/326242/) - -При использовании Stream API производительность улучшится только на больших задачах, где возможно распараллеливание. -Еще: просто так запустить и померить скорость JVM нельзя (как минимум надо дать прогреться и запустить очень большое число раз). Лучше использовать какие-нибудь бенчмарки, например [JMH](http://tutorials.jenkov.com/java-performance/jmh.html), который мы используем на другом проекте (Mastejava). - -## ![error](https://cloud.githubusercontent.com/assets/13649199/13672935/ef09ec1e-e6e7-11e5-9f79-d1641c05cbe6.png) Замечания к HW0 -- 1: Код проекта менять можно! Одна из распространенных ошибок как в тестовых заданиях на собеседовании, так и при работе на проекте, что ничего нельзя менять. Конечно, при правках в рабочем проекте обязательно нужно проконсультироваться/проревьюироваться у авторов кода (находятся по истории VCS) -- 2: Наследовать `UserMealWithExcess` от `UserMeal` нельзя, т. к. это разные сущности: Transfer Object и Entity. Мы будем их проходить на 2-м уроке. Это относится и к их зависимости друг от друга. -- 3: Правильная реализация должна быть простой и красивой, можно сделать 2-мя способами: через стримы и через циклы. Сложность должна быть O(N), т. е. без вложенных стримов и циклов. -- 4: При реализации через циклы посмотрите в `Map` на методы `getOrDefault` или `merge` -- 5: **При реализации через `Stream` заменяйте `forEach` оператором `stream.map(..)`** -- 6: Объявляйте переменные непосредственно перед использованием (если возможно - сразу с инициализацией). При объявлении коллекций в качестве типа переменной используйте интерфейс (Map, List, ..) -- 7: Если IDEA предлагает оптимизацию (желтым подчеркивает), например, заменить лямбду на ссылку на метод (method reference), соглашайтесь (Alt+Enter) -- 8: Пользуйтесь форматированием кода в IDEA: `Alt+Ctrl+L` -- 9: Перед check-in (отправкой изменений на GitHub) просматривайте внесенные изменения (Git -> [Log](https://www.jetbrains.com/help/idea/log-tab.html) -> курсор на файл и Ctrl+D): не оставляйте в коде ничего лишнего (закомментированный код, TODO и пр.). Если файл не меняется (например только пробелы или переводы строк), не надо его чекинить, делайте ему `revert` (Git -> Revert / `Ctrl+Alt+Z`). -- 10: `System.out.println` нельзя использовать нигде, кроме как в `main`. Позже введем логирование. -- 11: Результаты, возвращаемые `UserMealsUtil.filteredByStreams`, мы будем использовать [в нашем приложении](http://javaops-demo.ru/topjava) для фильтрации по времени и отображения еды правильным цветом. -- 12: Обращайте внимание на комментарии к вашим коммитам в Git. Они должны быть короткие и информативные (лучше на english) -- 13: Не полагайтесь в решении на то, что список еды будет подаваться отсортированным. Такого условия нет. ------ - -> - ДЗ первого урока будет связано с созданием небольшого [CRUD](https://ru.wikipedia.org/wiki/CRUD)-приложения (в памяти, без базы данных) на JSP и сервлетах -> - основы JavaScript необходимы для понимания проекта, начиная с 8-го занятия - -### Полезные ресурсы -#### HTML, JavaScript, CSS -- [Basic HTML and HTML5](https://learn.freecodecamp.org/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements/) -- [Справочник по WEB](https://developer.mozilla.org/ru/) -- [Видео по WEB-технологиям](https://www.youtube.com/user/WebMagistersRu/playlists) -- [Изучение JavaScript в одном видеоуроке за час](https://www.youtube.com/watch?v=QBWWplFkdzw) -- HTML, CSS, JAVASCRIPT, SQL, JQUERY, BOOTSTRAP -- Введение в программирование на JavaScript -- Стандарты кодирования для HTML, CSS и JavaScript’a -- Основы работы с HTML/CSS/JavaScript -- JavaScript - Основы -- Основы JavaScript -- Bootstrap 3 - Основы -- jQuery для начинающих - -#### Java (базовые вещи) -- [Сборник видео "Изучаем Java"](https://www.youtube.com/playlist?list=PLyxk-1FCKqockmP-fXZmHQ7UlYP3qvZRa) -- 1-й урок MasterJava: Многопоточность -- [Основы Java garbage collection](http://web.archive.org/web/20180831013112/https://ggenikus.github.io/blog/2014/05/04/gc) -- Размер Java объектов -- Введение в Java Reflection API -- Структуры данных в картинках -- Обзор java.util.concurrent.* -- Синхронизация потоков -- String literal pool -- Маленькие хитрости Java -- A Guide to Java 8 - -### Туториалы, разное -- [Открытый курс: Spring Boot + HATEOAS](https://javaops.ru/view/bootjava) -- [Что нужно знать о бэкенде новичку в веб-разработке](https://tproger.ru/translations/backend-web-development) -- [Туториалы: Spring Framework, Hibernate, Java Core, JDBC](http://proselyte.net/tutorials/) - -#### Сервлеты -- Как создать Servlet? Полное руководство. -- [Сервлеты](https://metanit.com/java/javaee/4.1.php) - -#### Туториалы по Spring -- [Юрий Ткач: Spring Framework - The Basics](https://www.youtube.com/playlist?list=PL6jg6AGdCNaWF-sUH2QDudBRXo54zuN1t) -- [Java Brains: Spring Framework](https://www.youtube.com/playlist?list=PLC97BDEFDCDD169D7) -- [Тимур Батыршинов: Spring Core - основы фреймворка, ядро](https://www.youtube.com/watch?v=CfHDr-19WWY&list=PL8X2nqRlWfaYYP1-qXjdPKE7bXYkl6aL4) -- [alishev: Spring Framework](https://www.youtube.com/playlist?list=PLAma_mKffTOR5o0WNHnY0mTjKxnCgSXrZ) - -#### JDBC, SQL -- Основы SQL на примере задачи -- Уроки по JDBC -- Learn SQL -- Интуит. Основы SQL -- Try SQL -- Курс "Введение в базы данных" - -#### Разное -- Вопросы по собеседованию, ресурсы для подготовки -- Эффективная работа с кодом в IntelliJ IDEA -- Quizful- тесты онлайн -- Введение в Linux - -#### Книги -- Джошуа Блох: Java. Эффективное программирование. Второе издание -- Гамма, Хелм, Джонсон: Приемы объектно-ориентированного проектирования. Паттерны проектирования -- Редмонд Э.: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL -- Brian Goetz: Java Concurrency in Practice -- G.L. McDowell: Cracking the Coding Interview +### 22.04: Миграция на Spring-Boot +- Ревью вашего резюме +- Основы Spring Boot. Spring Boot maven plugin +- Lombok, база H2, ApplicationRunner +- Spring Data REST + HATEOAS +- Миграция приложения подсчета калорий на Spring Boot + +### 12.05.24: Дедлайн на сдачу [выпускного проекта](https://github.com/JavaOPs/topjava/blob/master/graduation.md) +### 22.05.24: Получение дипломов для участников [Дипломной программы](https://javaops.ru/view/register/diploma) diff --git a/lessons/Lesson_11/lesson12.md b/lessons/Lesson_11/lesson12.md new file mode 100644 index 000000000000..d782c6a1db19 --- /dev/null +++ b/lessons/Lesson_11/lesson12.md @@ -0,0 +1,45 @@ +# Стажировка Topjava + +## [Патчи занятия](https://drive.google.com/drive/u/1/folders/1sizknxR29Yu7XXjaVIBdS88ffXiVuqiB) + +## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Финальные правки: + +Один из вариантов сокрытия полей в примерах Swagger - сделать специальный TO класс. Но можно сделать проще через специальные аннотации: [Hide a Request Field in Swagger API](https://www.baeldung.com/spring-swagger-hide-field) +- Скрываем необязательные поле `id` при POST и PUT запросах через `@ApiModelProperty(hidden = true)` в примерах запроса Swagger. При этом передавать поле в запросе можно. +- `Meal.user` отсутствует в REST API, можно игнорировать: `@JsonIgnore` +- `User.meals` можно было сделать `JsonProperty.Access.READ_ONLY`, но при этом не пройдут тесты `getWithMeals` (maels не будет сериализоваться из ответа сервера для сравнения). Скрыл также через `@ApiModelProperty(hidden = true)` +- Также можно было скрыть нулевое поле `User.meals` при выводе через `@JsonInclude(JsonInclude.Include.NON_EMPTY)`. Но при этом поле исчезнет при запросе `getWithMeals` пользователя с пустым списком еды (например для Guest). Все зависит от бизнес-требований приложения (например насколько API публично и должно быть красивым). Можете попробовать самостоятельно скрыть это поле из вывода для запросов без еды через `View` (или отдельный TO). + +#### Apply [11_16_HW_fix_swagger.patch](https://drive.google.com/file/d/1A76XXvZdZCKxeKnVjZ2VkrWAHEQ1iof2) + +## Миграция на Spring Boot +За основу взят **[финальный код проекта BootJava с миграцией на Spring Boot 3.2, 8-й урок](https://javaops.ru/view/bootjava/lesson08)** +Вычекайте в отдельную папку (как отдельный проект) ветку `spring_boot` нашего проекта (так удобнее, не придется постоянно переключаться между ветками): +``` +git clone --branch spring_boot --single-branch https://github.com/JavaWebinar/topjava.git topjava_boot +``` +Если будете его менять, [настройте `git remote`](https://javaops.ru/view/bootjava/lesson01#project) +> Если захотите сами накатить патчи, сделайте ветку `spring_boot` от первого `init` и в корне **создайте каталог `src\test`** + +---- + +#### Apply 12_1_init_boot_java +Оставил как в TopJava название приложения `Calories Management` и имя базы `topjava` + +#### Apply 12_2_add_calories_meals + +Добавил из TopJava: +- Еду, калории +- Таблицы назвал в единственном числе: `user_role, meal` (кроме `users`, _user_ зарезервированное слово) +- Общие вещи (пусть небольшие) вынес в сервис : `MealService` +- Проверку принадлежности еды делаю в `MealRepository.getBelonged` +- Вместо своих конверторов использую `@DateTimeFormat` +- Обратите внимание на `UserRepository.getWithMeals` - он не работает с `@EntityGraph`. Зато работает с обычным `JOIN FETCH` и `DISTINCT` больше не нужен: + - [forget about DISTINCT](https://vladmihalcea.com/spring-6-migration/#Auto-deduplication) + - [it is no longer necessary to use distinct in JPQL and HQL](https://docs.jboss.org/hibernate/orm/6.0/migration-guide/migration-guide.html#query-sqm-distinct) +- Мигрировал все тесты контроллеров. В выпускном проекте столько тестов необязательно! Достаточно нескольких, на основные юзкейсы. +- Кэширование в выпускном желательно. 7 раз подумайте, что будете кэшировать! **Максимально просто, самые частые запросы, которые редко изменяются**. +- **Добавьте в свой выпускной OpenApi/Swagger - это будет большим плюсом и избавит от необходимости писать документацию**. + +### За основу выпускного предлагаю взять этот код миграции, сделав свой выпускной МАКСИМАЛЬНО в этом стиле. +### Успехов с выпускным проектом и в карьере! diff --git a/lessons/lesson01.md b/lessons/lesson01.md new file mode 100644 index 000000000000..087ea3cddb9f --- /dev/null +++ b/lessons/lesson01.md @@ -0,0 +1,263 @@ +# Стажировка Topjava + +### Правила похождения стажировки +- Не стоит стремиться прочитать все ссылки урока, их можно использовать позднее как справочник. Гораздо важнее **пройти основной материал урока и сделать Домашнее Задание** +- Обязательно посмотри правила работы с патчами на проекте + - Делать Apply Patch лучше по одному, непосредственно перед видео на эту тему, а при просмотре видео сразу отслеживать все изменения кода проекта по изменению в патче (`Git-> Local Changes-> Ctrl+D`) + - **При первом Apply удобнее выбрать имя локального ченджлиста Name: Change**. Далее все остальные патчи также будут в него попадать. +- **Код проекта обновляется и не всегда совпадает с видео (можно увидеть как развивался проект). Изменения в проекте указываю после соответствующего патча.** +- Если ссылка не открывается, попробуй [включить VPN](https://github.com/JavaOPs/topjava/wiki/VPN) +- **ОСНОВНОЕ, чему мы учимся на проекте: мыслить и работать как Java разработчики уже сейчас**, потом это будет гораздо сложнее и стоить дороже. Вот на мой взгляд [хорошие советы новичкам](http://blog.csssr.ru/2016/09/19/how-to-be-a-beginner-developer). От себя я добавлю: + - Учись **грамотно формулировать проблему**. Проблема "у меня не работает" может иметь тысячи причин. В процессе формулирования очень часто приходит ее решение. + - что я делаю (подробно, чтобы понял человек, который не был занят этой проблемой несколько часов) + - что получаю (обычно верх самого последнего эксепшена) + - что я сделал для решения, какие результаты получил + - Учись исследовать проблему. Внимательное чтение логов и [умение дебажить](http://info.javarush.ru/idea_help/2014/01/22/Руководство-пользователя-IntelliJ-IDEA-Отладчик-.html) - основные навыки разработчика. Обычно самый верх самого нижнего эксепшена- причина ошибки, туда нужно ставить брекпойнт. + - Грамотно **уделяй время каждой проблеме**. Две крайности - сразу бросаться за помощью и биться над ней часами. Пробуй решить ее сам и в зависимости от проблемы выделяй на это разумное время. + - Наконец, уровень участников у всех разный. Бывают синьоры, бывают начинающие. Не стесняйтесь задавать вопросы, иначе стажировка пройдет впустую! **Глупых вопросов не бывает**. +---------------------------------------------------- +- **Обязательно и как можно чаще пользуйтесь `Ctrl+Alt+L` - отформатировать код класса** +- **При изменениях на UI не забываетй сбрасывать кэш браузера - `Ctrl+F5`** +- **При удалении классов не забывате чистить target - в окошке Maven -> clean или `mvn clean`** +- **При проблемах с IDEA пользуйтесь `Refresh` в окошке Maven** +- **При проблемах с выполнением проверьте (и удалите) лишние java процессы (например в Task Manager)** + + +## Материалы занятия (скачать все патчи можно через `Download/Скачать` папки patch) +![image](https://cloud.githubusercontent.com/assets/13649199/18330295/5f2ca214-7560-11e6-8e1e-c0494f798c37.png) + +### ![correction](https://cloud.githubusercontent.com/assets/13649199/13672935/ef09ec1e-e6e7-11e5-9f79-d1641c05cbe6.png) Рефакторинг проекта + +#### Apply 1_0_rename.patch +- переименовал классы `UserMeal*` в более красивые `Meal*` +- преименовал `MealWithExceed` transfer object класс ([что это такое](https://ru.wikipedia.org/wiki/DTO) пройдем позже) в `MealTo` ([data transfer object naming convention](https://stackoverflow.com/questions/1724774/java-data-transfer-object-naming-convention)) +- обновил зависимость `maven-compiler-plugin` + +## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Разбор домашнего задания HW0: +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. Optional: реализация getFilteredMealsWithExcess через Stream API +- В патче `prepare_to_HW0.patch` вступительного задания метод фильтрации в `TimeUtil` переименовали в `isBetweenHalfOpen` (также изменилась логика сравнения - `startTime` включается в интервал) + +#### Apply 1_1_HW0_streams.patch + +- [Презентация Java 8](https://docs.google.com/presentation/d/1oltLkHK60FqIdsXjUdm4pPLSeC6KpNYjDsM0ips-qBw) + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2. Работа с git в IDEA. Реализация через цикл. +### ВНИМАНИЕ! Патчей `1_opt_2_HW0_cycles` и `1_opt_3_HW0_opt2` не будет в проекте! +Делаем в отдельной ветке (у меня `MealsUtil_opt`). Это варианты решений, которые не идут в `master` + +![image](https://user-images.githubusercontent.com/13649199/83656711-8b758b00-a5c8-11ea-9de4-c2ade77d4598.png) + +#### Apply 1_opt_2_HW0_cycles.patch + +### ![question](https://cloud.githubusercontent.com/assets/13649199/13672858/9cd58692-e6e7-11e5-905d-c295d2a456f1.png) Вопросы по HW0 + +> Почему не использовать в `TimeUtil` методы `isBefore/isAfter` ? + +это строгие (excluded) сравнения, а нам также нужно краевые значения + +> В `MealsUtil` у нас где-то есть ключевое слово `final`, где-то нет. В чем разница? + +Я участвовал в одном проекте, где `final` был обязательным (в сеттингах IDEA галочка стояла). Но это скорее исключение, чем правило в проектах java (в Java 8 вообще ввели эффективный final, те по факту). Во всех новомодных языках переменные final по умолчанию, а в java нужно помнить и везде добавлять, утомительно. Но если приучитесь - хуже не будет. Я обычно ставлю там, где важно по смыслу (если не забываю). + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. [HW0 Optional 2: реализация в один проход циклами и Stream API](https://drive.google.com/file/d/1dSt3axySxu4V9dMnuR1wczerlI_WzCep) + +#### Apply 1_opt_3_HW0_opt2.patch +- Дополнительно: + - [Первое занятие MasterJava: многопоточность](https://github.com/JavaOPs/masterjava) + - [Обзор java.util.concurrent.*](https://web.archive.org/web/20220427140138/https://habr.com/ru/company/luxoft/blog/157273/) + +## Занятие 1: + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Интервью: Java разработка. Обучение. Трудоустройство](https://javaops.ru/view/news/javaInterview) +- [JetBrains devecosystem 2022](https://www.jetbrains.com/lp/devecosystem-2022/java/) +- [Сontinuum Java Ecosystem 2022 – Survey results](https://www.continuum.be/en/blog/the-java-ecosystem-2022-survey-results/) +- [JRebel 2022 Java Developer Productivity Report](https://drive.google.com/file/d/1txLeRsNNR7EqYEeIvYmuyQi9hknBeR9G) + +## Внимание - обновил все патчи ниже 01.06 в 20:17. Если уже забрали, пожалуйста [скачайте заново](https://drive.google.com/drive/u/2/folders/0B9Ye2auQ_NsFfm5hSHEtbmxmN2kxb0NocVRwWl9KanowWXVCVXRZTlhaM09wQUswZkRidTA?resourcekey=0-H0PjelYVCYFR_1ANk-we5w) +### ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) 5. [Servlet API. Apache Tomcat. JSP](lesson01/tomcat_servlet_war.md) + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 6. [Логирование](https://www.youtube.com/watch?v=mo8z3zRVV1E) +#### Последние версии _logback / slf4j_ не работают с JDK 8, понизил версии до совместимых с ней. Поднимем на 5м занятии при миграции на JDK 17+ + +#### Apply 1_5_simple_logging.patch + +- [Зачем нужно логирование](https://javarush.ru/groups/posts/2293-zachem-nuzhno-logirovanie) +- [Logback Project](https://logback.qos.ch/) + +> А зачем мы использовали logback? Почему SLF4J нас не устроило? Почему реализация логирования не log4j? + +`SLF4J-API` это API. В нее включена только пустая реализация `org.slf4j.helpers.NOPLogger` (можно посмотреть в исходниках). Logback для новых проектов стал стандарт, *Spring Boot* используют его по умолчанию. +[Reasons to prefer logback over log4j](http://logback.qos.ch/reasonsToSwitch.html) + +> Почему `private static final Logger log` а не `LOG/LOGGER` ? + +Это [правило именования констант, которые не "deeply immutable"](https://google.github.io/styleguide/javaguide.html#s5.2.4-constant-names), те если их содержимое можно изменить. + +#### Apply 1_6_logging_config.patch + +- [Java Logging: история кошмара](http://habrahabr.ru/post/113145/) +- [Project dependencies for logging](https://www.slf4j.org/manual.html#projectDep) +- [Добавление зависимостей логирования](http://www.slf4j.org/legacy.html) в проект +- Не делать конкатенацию строк: [форматирование в логах через {}](https://www.slf4j.org/faq.html#logging_performance) +- Дополнительно: + - [Logback configuration](https://logback.qos.ch/manual/configuration.html) + - [Ведение лога приложения](http://www.skipy.ru/useful/logging.html) + - [Владимир Красильщик – Что надо знать о логировании прагматичному Java‑программисту](https://www.youtube.com/watch?v=qzqAUUgB3v8) + +**Установите переменную окружения на TOPJAVA_ROOT на корень проекта и перезапустите IDEA. Слеши в пути должны быть в стиле unix (/)** + +Проверить, видит ли Java вашу переменную можно через `System.getenv("TOPJAVA_ROOT")` + +- [Set environment for Win/Mac/Unix](https://chlee.co/how-to-setup-environment-variables-for-windows-mac-and-linux/) +- [Set environment for UNIX (advanced)](https://askubuntu.com/a/849954) + - [Определить, какой Login или Non-Login Shell](https://tecadmin.net/difference-between-login-and-non-login-shell) + - [Порядок запуска скриптов при старте](https://www.baeldung.com/linux/bashrc-vs-bash-profile-vs-profile) +- Или простой вариант (не забудте добавить и в Run, и в Debug) + +![image](https://user-images.githubusercontent.com/13649199/76862707-8af21180-686f-11ea-9f8c-2bb30ef4c3b2.png) + +**Иногда антивирусы блокируют логирование (например Comodo). Если не работает и стоит антивирус- добавьте исключение.** + +> Изменения в проекте, которым могут встретиться в других видео: +> - убрал `LoggerWrapper` и логирую напрямую в логгер SLF4J. +> - удалил зависимости `jul-to-slf4j` и `jcl-over-slf4j`. Spring 5 напрямую использует `slf4j` без `common-logging` + +--------- + +## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Домашнее задание HW01 (делаем ветку HW01 от последнего патча в master) +-------------------------------------------- +#### 1. Реализовать сервлет с отображением в таблице списка еды (в памяти и БЕЗ учета пользователя) + +> Деплоиться в Tomcat лучше как `war exploded`: нет упаковки в war и при нажатой кнопке `Update Resources on Frame Deactivation` можно обновляться css, html, jsp без передеплоя. При изменении `web.xml`, добавлении методов, классов необходим redeploy. + +- 1.1 По аналогии с `UserServlet` добавить `MealServlet` и `meals.jsp` + - Задеплоить приложение (war) в Tomcat c `applicationContext=topjava` (приложение должно быть доступно по http://localhost:8080/topjava) + - Попробовать деплои в Tomcat как WAR в запушенный вручную Tomcat и через IDEA. +- 1.2 Сделать отображения списка еды в JSP [в таблице](http://htmlbook.ru/html/table), цвет записи в таблице зависит от параметра `excess` (красный/зеленый). + - 1.2.1 Список еды захардкодить (те проинициализировать в коде, желательно чтобы в проекте инициализация была только в одном месте). Норму калорий (caloriesPerDay) сделать в коде константой + - 1.2.2 Время выводить без 'T' + - 1.2.3 Список выводим БЕЗ фильтрации по `startTime/endTime` + - 1.2.4 С обработкой исключений пока можно не заморачиваться, мы будем красиво обрабатывать в конце стажировки + - 1.2.5 Вариант реализации: + - из сервлета преобразуете еду в `List
Date | +Description | +Calories | ++ | + |
---|---|---|---|---|
+ <%--${meal.dateTime.toLocalDate()} ${meal.dateTime.toLocalTime()}--%> + <%--<%=TimeUtil.toString(meal.getDateTime())%>--%> + <%--${fn:replace(meal.dateTime, 'T', ' ')}--%> + ${fn:formatDateTime(meal.dateTime)} + | +${meal.description} | +${meal.calories} | +Update | +Delete | +
+ * Comparing actual and expected objects via AssertJ
+ */
+public class MatcherFactory {
+ public static