diff --git a/.codacy.yml b/.codacy.yml new file mode 100644 index 000000000..311a8f4e0 --- /dev/null +++ b/.codacy.yml @@ -0,0 +1,5 @@ +--- +exclude_paths: + - 'src/main/webapp/**' + - '**.md' + - '**.sql' \ No newline at end of file diff --git a/README.md b/README.md index 3b94b09e2..b038e9ad3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[](https://app.codacy.com/gh/JavaWebinar/topjava/dashboard) + Java Enterprise Online Project =============================== @@ -9,13 +11,13 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - [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://topjava.herokuapp.com/) +- [Демо разрабатываемого приложения](http://javaops-demo.ru/topjava) -### 26.01: Старт проекта +### 28.09: Старт проекта - Начало проверки [вступительного задания HW0](https://github.com/JavaOPs/topjava#-Домашнее-задание-hw0) -#### 31.01 Дедлайн на сдачу HW0 -### 02.02: 1-е занятие +#### 03.10 Дедлайн на сдачу HW0 +### 05.10: 1-е занятие - Разбор домашнего задания вступительного занятия (вместе с Optional) - Обзор используемых в проекте технологий. Интеграция ПО - Maven @@ -24,8 +26,8 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Уровни и зависимости логгирования. JMX - Домашнее задание 1-го занятия (HW1 + Optional) -#### 09.10 Дедлайн подачи заявки на [дипломную программу](https://javaops.ru/view/register/diploma) -### 09.02: 2-е занятие +#### 12.10 Дедлайн подачи заявки на [дипломную программу](https://javaops.ru/view/register/diploma) +### 12.10: 2-е занятие - Разбор домашнего задания HW1 + Optional - Библиотека vs Фреймворк. Стандартные библиотеки Apache Commons, Guava - Слои приложения. Создание каркаса приложения @@ -33,7 +35,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Пояснения к HW2. Обработка Autowired - Домашнее задание (HW2 + Optional) -### 16.02: 3-е занятие +### 19.10: 3-е занятие - Разбор домашнего задания HW2 + Optional - Жизненный цикл Spring контекста - Тестирование через JUnit @@ -46,7 +48,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Логирование тестов - Домашнее задание (HW3 + Optional) -### 23.02: 4-е занятие +### 26.10: 4-е занятие - Разбор домашнего задания HW3 + Optional - Методы улучшения качества кода - Spring: инициализация и популирование DB @@ -56,7 +58,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Домашнее задание (HW4 + Optional) #### Начало выполнения [выпускного проекта](https://github.com/JavaOPs/topjava/blob/master/graduation.md) -### 02.03: 5-е занятие +### 02.11: 5-е занятие - Обзор JDK 9/17. Миграция Topjava с 1.8 на 17 - Разбор вопросов - Разбор домашнего задания HW4 + Optional @@ -67,7 +69,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Spring кэш - Домашнее задание (HW5 + Optional) -### 09.03: 6-е занятие +### 09.11: 6-е занятие - Разбор домашнего задания HW5 + Optional - Кэш Hibernate - Spring Web @@ -80,7 +82,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + #### Большое ДЗ + выпускной проект + начинаем [курс BootJava](https://javaops.ru/view/bootjava) + подтягиваем "хвосты". -### 23.03: 7-е занятие +### 23.11: 7-е занятие - Разбор домашнего задания HW6 + Optional - Автогенерация DDL по модели - Тестирование Spring MVC @@ -91,7 +93,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Тестирование через SoapUi. UTF-8 - Домашнее задание (HW7 + Optional) -### 30.03: 8-е занятие +### 30.11: 8-е занятие - Разбор домашнего задания HW7 + Optional - WebJars. jQuery и JavaScript frameworks - Bootstrap @@ -100,7 +102,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Добавление Spring Security - Домашнее задание (HW8 + Optional) -### 06.04: 9-е занятие +### 07.12: 9-е занятие - Разбор домашнего задания HW8 + Optional - Spring Binding - Spring Validation @@ -112,7 +114,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Cookie. Session - Домашнее задание (HW9 + Optional) -### 13.04: 10-е занятие +### 14.12: 10-е занятие - Разбор домашнего задания HW10 + Optional - Кастомизация JSON (@JsonView) и валидации (groups) - Рефакторинг: jQuery конверторы и группы валидации по умолчанию @@ -125,7 +127,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Защита от межсайтовой подделки запросов (CSRF) - Домашнее задание (HW10) -### 20.04: 11-е занятие +### 21.12: 11-е занятие - Разбор домашнего задания HW10 + Optional - Локализация datatables, ошибок валидации - Защита от XSS (Cross Site Scripting) @@ -136,12 +138,12 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Домашнее задание (HW11): сокрытия полей в Swagger - Составление резюме. Собеседование. Разработка ПО. Возможные доработки приложения -### 24.04: Миграция на Spring-Boot +### 25.12: Миграция на Spring-Boot - Ревью вашего резюме - Основы Spring Boot. Spring Boot maven plugin - Lombok, база H2, ApplicationRunner - Spring Data REST + HATEOAS - Миграция приложения подсчета калорий на Spring Boot -### 14.05.23: Дедлайн на сдачу [выпускного проекта](https://github.com/JavaOPs/topjava/blob/master/graduation.md) -### 24.05.23: Получение дипломов для участников [Дипломной программы](https://javaops.ru/view/register/diploma) +### 13.01.24: Дедлайн на сдачу [выпускного проекта](https://github.com/JavaOPs/topjava/blob/master/graduation.md) +### 24.01.24: Получение дипломов для участников [Дипломной программы](https://javaops.ru/view/register/diploma) diff --git a/config/messages/app.properties b/config/messages/app.properties new file mode 100644 index 000000000..ccd4c66b5 --- /dev/null +++ b/config/messages/app.properties @@ -0,0 +1,12 @@ +app.title=Calories management +app.home=Home +app.footer=Internship Spring 5/JPA Enterprise (Topjava) application +app.login=Login as +user.title=Users +user.name=Name +user.email=Email +user.roles=Roles +user.active=Active +user.registered=Registered +meal.title=Meals +common.select=Select \ No newline at end of file diff --git a/config/messages/app_ru.properties b/config/messages/app_ru.properties new file mode 100644 index 000000000..f22faf3cc --- /dev/null +++ b/config/messages/app_ru.properties @@ -0,0 +1,12 @@ +app.title=Подсчет калорий +app.home=Главная +app.footer=Приложение стажировки Spring 5/JPA Enterprise (Topjava) +app.login=Зайти как +user.title=Пользователи +user.name=Имя +user.email=Почта +user.roles=Роли +user.active=Активный +user.registered=Зарегистрирован +meal.title=Моя еда +common.select=Выбрать \ No newline at end of file diff --git a/doc/entrance.md b/doc/entrance.md new file mode 100644 index 000000000..e3b670aad --- /dev/null +++ b/doc/entrance.md @@ -0,0 +1,247 @@ +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. + + + + Когда вы слышите что-то, вы забываете это. + Когда вы видите что-то, вы запоминаете это. + Но только когда вы начинаете делать это, + вы начинаете понимать это + + Старинная китайская поговорка + +## Демо разрабатываемого приложения + +Обновленное вводное занятие (обязательно смотреть все видео) +=============== +##  1. [Вступление, история, команда, источники](entrance/video1.md) + +## Обзор наиболее востребованных технологий, которые будут изучаться на курсе TopJava +##  2.1. [Часть 1: инфраструктура](entrance/video2.1.md) + +##  2.2. [Часть 2: frameworks Spring, ORM](entrance/video2.2.md) + +##  2.3. [Часть 3: тренды](entrance/video2.3.md) + +##  2.3. [Часть 4: обзор разрабатываемого приложения](entrance/video2.4.md) + +##  3. [Рекомендуемые подходы к обучению на курсе](entrance/video3.md) + +##  4. [Структура приложения (многоуровневая архитектура)](entrance/video4.md) +### [Демо приложения](http://javaops-demo.ru/topjava) + +##  5. [Системы управления версиями. Git](entrance/video5-vcs-git.md) + +##  6. Работа с проектом (выполнять инструкции) +- Поправка: JetBrains больше не выдает ключей, вот [варианты после trial](https://github.com/JavaOPs/topjava/wiki/IDEA#licence) +- **ВНИМАНИЕ: выбирайте для проекта простой пусть без пробелов и русских букв, например, `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`: + +  + +### Патч [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) + +## Инструкция по шагам (из видео): +- Установить ПО (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](https://drive.google.com/file/d/1LNPpu9OkuCpfpD8ZJHO-o0vwu49p2i5M) +- Закоммитить и запушить изменения (`commit` + `push`) +- Сделать ветку домашнего задания +- Выполнить задание и залить на GitHub (`commit` + `push`) +- Переключиться в основную ветку проекта `master`. + +##  7. [Maven](https://drive.google.com/file/d/1qEJTwv9FNUQjx-y9MSydH01xaAne0-hu) +- [Руководство по 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) + +##  8. [Как правильно относиться к техзаданию (ТЗ). Полуоткрытый интервал.](https://drive.google.com/file/d/1BpTzjNFjS0TSekCyt_xvt6YoLvuw5KTZ) +- [Типы промежутков](https://ru.wikipedia.org/wiki/Промежуток_(математика)) + +##  Домашнее задание 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). + +##  Замечания к 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 +- [Основы HTML от mozilla](https://developer.mozilla.org/ru/docs/Learn/Getting_started_with_the_web/HTML_basics) +- [Основы HTML от webref](https://webref.ru/course/html-basics) +- [Учебник HTML для начинающих](https://msiter.ru/tutorials/html-nachalnogo-urovnya) +- [HTML для чайников](https://site-do.ru/html/) +- [Основы HTML (видео от учеников JavaRush)](https://www.youtube.com/watch?v=BdsA7VCLRc8) + +#### Web, JavaScript, CSS +- [Знакомство с HTML и CSS](https://htmlacademy.ru/courses/basic-html-css) +- [Справочник по 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) + +#### 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 diff --git a/doc/graduation.md b/doc/graduation.md new file mode 100644 index 000000000..293de57a5 --- /dev/null +++ b/doc/graduation.md @@ -0,0 +1,189 @@ +## Выпускной проект + +- **Дедлайн на заполнение [формы по выпускному проекту](https://javaops.ru/auth/graduate) - 14 января 2024, 23.59 МСК** +- Ревью проекта входит в участие с проверкой домашних заданий. Проверяется два раза: один раз ассистентами и после ваших правок - финальная проверка, Кислиным Григорием. +- Ревью выпускного делается только у участников с проверкой ДЗ. У кого оплачен Диплом, но нет проверки - даю краткие итоги. +- **Ревью выпускного можно оплатить отдельно как [техническое собеседование](https://javaops.ru/auth/payonline?payId=I)** +- Участникам проекта [Многомодульный maven. Многопоточность. XML (JAXB/StAX). Веб сервисы (JAX-RS/SOAP). Удаленное взаимодействие (JMS/AKKA) (Masterjava)](http://javaops.ru/reg/masterjava) срок ревью выпускного до + 14.04.2024. Но это не влияет на сроки сдачи, если Дипломная программа! +- Заключившим образовательный договор с Виакадемией: **для получение диплома требуется сдача выпускного проекта (либо любого другого, даже рабочего, на нашем стеке)**. В случае, если Вы его не успеете его + сделать в срок, указанный в договоре, **заранее оформляется академический отпуск**. + +## Technical requirement: +Design and implement a REST API using Hibernate/Spring/SpringMVC (Spring-Boot preferred!) **without frontend**. + +The task is: + +Build a voting system for deciding where to have lunch. + +* 2 types of users: admin and regular users +* Admin can input a restaurant and it's lunch menu of the day (2-5 items usually, just a dish name and price) +* Menu changes each day (admins do the updates) +* Users can vote for a restaurant they want to have lunch at today +* Only one vote counted per user +* If user votes again the same day: + - If it is before 11:00 we assume that he changed his mind. + - If it is after 11:00 then it is too late, vote can't be changed + +Each restaurant provides a new menu each day. + +As a result, provide a link to github repository. It should contain the code, README.md with API documentation and couple curl commands to test it (**better - link to Swagger**). + +----------------------------- +P.S.: Make sure everything works with latest version that is on github :) +P.P.S.: Assume that your API will be used by a frontend developer to build frontend on top of that. + +----------------------------- + +##  Рекомендации + +**Пишем выпускной проект как тестовое задание на работу** + +- **Не списывай с коллег!** Выпускные проекты пишут только наши выпускники, их репозитории есть в нашей базе. Поэтому при подозрениях на списывание оригинал вычисляется легко. Лучше написать свое - + как можете, как поняли материал - и получить ревью (которое вами же оплачено) своего проекта, а не чужого. Даже если времени мало - сделайте основное. Если с Дипломом - это с очень большой + вероятностью 4, вместо отчисления +- **Не изобретай велосипедов!** Грубая ошибка - пытаться сделать стандартные вещи по-своему, чаще всего криво. На проекте все должно быть единообразно! Ваш проект TopJava - сделай все МАКСИМАЛЬНО в + этом стиле. Если тебе кажется, что есть лучшее решение, чем в TopJava - пишите мне в личку, я всегда открыт для улучшений. +- **Рекомендую писать проект на востребованном на рынке стеке**: Spring Boot + Spring Data JPA (работа с БД) + Swagger/OpenAPI 3.0 (REST документация). Для старта оптимально подойдет код миграции + TopJava на Spring Boot в конце стажировки на основе **открытого курса [Spring Boot 2.x + HATEOAS](https://javaops.ru/view/bootjava)**. + +*Представьте себе, что ПМ (лид, архитектор) дал вам ТЗ и некоторое время недоступен. У вас, конечно, есть много мыслей, для чего нужно приложение, как исправить ТЗ, дополнить его и сделать правильно. +НО НЕ НАДО ИХ РЕАЛИЗОВЫВАТЬ В КОДЕ. Нужно сделать все строго по ТЗ, максимально просто, удобно для доработок и для использования со стороны клиента.* + +> Совершенство достигнуто не тогда, когда нечего добавить, а тогда, когда нечего отнять + +_Антуан де Сент-Экзюпери_ + +### 1: ТЗ (Тех.задание) + +- 1.1: Читай ТЗ ОЧЕНЬ внимательно, НЕ надо ничего своего туда домысливать и творчески изменять +- 1.2: Учитывай, что пользователей может быть ОООЧЕНЬ много, а админов - МАЛО +- 1.3: Сначала сделай основные сценарии по ТЗ. Все остальное (если очень хочется, 3 раза подумай) - потом. + +### 2. API + +- 2.1: API продумывай с точки зрения не программиста и объектов, а с точки зрения того, кто им будет пользоваться (клиента, UI) +- 2.1: Тщательно считайте количество запросов в вашем API для отображения нужной информации +- 2.3: Из потребностей приложения (клиента) реализуй только очевидные сценарии. Необходимо и достаточно: ВСЕ НЕОБХОДИМОЕ для клиента и НИЧЕГО ЛИШНЕГО. Процесс творческий, приходит с опытом. +- 2.4: Делаем REST API в соответствии с концепцией REST (url в общем имеют вид`{ресурс}/{id_ресурсa}[/{подресурс}/{id_подресурсa}][параметры]`, см. ниже ссылки про REST и иерархию). Имена ресурсов во множественном числе! + Самая распространенная и грубая ошибка - не придерживаться этих простых правил. + - **[15 тривиальных фактов о правильной работе с протоколом HTTP](https://habrahabr.ru/company/yandex/blog/265569/)** + - **[10 Best Practices for Better RESTful API](https://medium.com/@mwaysolutions/10-best-practices-for-better-restful-api-cbe81b06f291)** + - **[REST resource hierarchy](https://stackoverflow.com/questions/20951419/what-are-best-practices-for-rest-nested-resources)** + - [Лучшие практики разработки REST API: правила 1-7,15-17](https://tproger.ru/translations/luchshie-praktiki-razrabotki-rest-api-20-sovetov/) +- 2.5: Разделение на роли я предпочитаю на уровне URL. Сразу и однозначно видно, какой API у админа, какое у пользователя (API админа начинается, например, с */admin/...*). +- 2.6: На управление (CRUD) ресторанами и едой должны быть ОТДЕЛЬНЫЕ контроллеры. Не надо все, что может админ, сваливать в одну кучу! Смотрите на результат операции - помещаете в этот контроллер! +- 2.7: Проверьте в Swagger, что в POST и PUT нет ничего лишнего, а в GET есть все необходимые данные. Например, при запросе голоса должен в ответе отображаться `id` ресторана, а не весь объект, при создании-редактировании ресторана в примерах swagger не должно быть меню и еды. +- 2.8: `Profile` означает, что данные принадлежат профилю пользователя. Все остальное называйте по-другому. +- 2.9: Отсутствие данных часто бывает "бизнес кейсом", те НЕ ошибкой в запросе или приложении. Исключение - это ошибка, например неверный `id`. Запрос на данные, которые могут быть, могут нет, не должен приводить к исключениям. Посмотрите в сторону `ResponseEntity.of()` +- 2.10: По REST URL должно быть однозначно понятно, какие будут параметры на входе и что ждать на выходе. Без сюрпризов! + +### 3: Код: + +- 3.1: Строго соблюдайте соглашения Java по именованию: пакеты ТОЛЬКО маленькими буквами, методы начинаются с маленькой буквы, классы с большой. Незнания Java Core - тестовое задание сразу в корзину. +- 3.2 В проекте (и тестовом задании на работу), в отличие от нашего учебного topjava, оставляйте только необходимый для работы по ТЗ приложения код, ничего лишнего + - 3.2.1: НЕ надо делать разные профили базы и работы с ней + - 3.2.2: НЕ надо делать абстрактных контроллеров на всякий случай + - 3.2.3: НЕ надо делать сервисов, если там нет ничего, кроме делегирования + - 3.2.4: НЕ нужны локализация, UI, типы ошибок, Json View +- 3.3: Название пакетов, имен классов для `model/to/web` стандартные (например `model/domain`). НЕ надо придумывать своих собственных правил +- 3.4: Проверьте, не торчат ли из кода учебные уши TopJava, типа `ProfileRestController.testUTF()`, `AbstractServiceTest.printResult()` или закомментированные `JdbcTemplate`. Назначение выпускного + совсем другое +- 3.5: Вместо `return ResponseEntity.ok(object)` в контроллерах пишите `return object`. Проще! + +### 4: Модель + +- 4.1: В БД обычно хранятся все введенные пользователем и админом данные c возможность их редактирования. Это означает, что мы не удаляем прошлые меню, а храним их в базе, как и историю голосования. Есть базовые вещи, которые закладываются в архитектуру приложения, и есть неочевидные доработки к ТЗ, делать не надо. +- 4.2: Не делайте в модели объектов, которые не будут использоваться в коде (например, не надо двунаправленных связей, если достаточно однонаправленных) +- 4.3: еще раз про [hashCode/equals в Entity](https://stackoverflow.com/questions/5031614/the-jpa-hashcode-equals-dilemma): не делайте в модели сравнение по полям! +- 4.4: ORM работает с объектами. [Иногда, для упрощения логики, fk_id как поля допустимы](https://stackoverflow.com/questions/6311776/hibernate-foreign-keys-instead-of-entities) + +### 5: Архитектура / pom + +- 5.1: Можно: + - или подключить DATA-REST (см.курс [Spring Boot 2.x + HATEOAS](https://javaops.ru/view/bootjava)). Контроллеры генерируются автоматически по репозиториям, требуется настройка ресурсов в кастомных контроллерах + - или делать на основе миграции TopJava / кода [TopJava-2](https://github.com/JavaOPs/topjava2) + +Нельзя смешивать эти подходы вместе! Я рекомендую 2-й вариант, без data-rest. Обязательно посмотрите в Swagger, какие контроллеры получились в результате. + +- 5.2: Не размещайте бизнес-логику приложения и преобразования в TO в слое доступа к DB +- 5.3: Не смешивайте TO и Entity вместе. Они должны быть независимыми друг от друга. На TopJava мы смотрели разные варианты [c использованием TO и без](https://stackoverflow.com/a/21569720/548473). + Делаем максимально просто. +- 5.4: [Use for money in java app](http://stackoverflow.com/a/43051227/548473) +- 5.5 Не надо явно указывать версии зависимостей в `pom`, если они наследуются от `spring-boot-starter-parent` + +### 6: Доступ к БД + +- 6.1: Используйте Spring Data JPA (без лишней делегации). Методы Repository можно вызывать напрямую из сервиса или из контроллера. +- 6.2: В DATA-JPA 2.x используются `Optional`. Попробуйте работать с ними, это безопасный способ работать с null-значениями (используйте `orElseThrow`) +- 6.3: Не делайте при обновлении записи ради экономии пары строчек кода так: + +``` +if(updateCondition) + repository.delete(entity) +} +repository.save(entity) +``` + +Обновление записи базы должно быть через `UPDATE`. + +### 7: База Данных + +- 7.1: Берите без установки (H2 или HSQLDB). Одну и **в памяти**! Ваше приложение должно сразу запуститься, без всяких настроек и переменных окружения +- 7.2: Тщательно считайте количество обращений в базу на каждый запрос. Особенно при запросах от юзеров, которых очень много! Также на сложность запросов от них, чтобы не положить базу +- 7.3: Сделайте [индексы к таблицам](https://ru.wikipedia.org/wiki/Индекс_(базы_данных)). Попробуйте обеспечить UNIQUE (один голос пользователя в день, один уникальный пункт меню в день). +Следите за **порядком полей в индексе**, от этого зависит индексирование запросов. +- 7.4: При популировании добавь записи за сегодняшний день - `now()`, чтобы всегда были актуальные исходные данные +- 7.5: Поля базы case insensitive, не пишите camelStyle (для которых нужны кавычки) +- 7.6: Таблицы обычно именуются в единственном числе. Исключение - `users`, `orders` и другие зарезервированные слова +- 7.7: `date`/`timestamp` - зарезервированное слово, лучше избегать их при именовании полей + +### 8: Security + +- 8.1: Проверьте, станет ли код проще с `@AuthenticationPrincipal` (урок 11, доступ к AuthorizedUser). +- 8.2: Я предпочитаю четкое разделение ролей на основе URL. Для админа URL содержит `/admin` +- 8.3: Еще раз - призываю не менять код TopJava + +### 9: Кэширование + +- 9.1: Кэширование желательно для частых и редко меняющихся запросов от пользователей. +Тщательно продумайте, что надо кэшировать (самые частые запросы), а что нет (большие или редко запрашиваемые данные) +- 9.2: Проверьте соответствие ключей к кэшу (параметры кэшируемого метода) с конфигурацией (например в singleNonExpiryCache, heap=1 в кэше может содержаться только ОДНО значение). + +### 10: Валидация + +- 10.1: Одних аннотаций валидации на полях недостаточно. Должны быть `@Valid/@Validation` в контроллере +- 10.2: Прячте `id` при `create/update` в примерах Swagger. Если их передали - проверяйте на соответствие (в TopJava это `ValidationUtil.checkNew()/assureIdConsistent()`) + +### 11: Дополнительно + +- 11.1: По возможности сделать JUnit-тесты. Можно не делать 100% покрытие, только основные сценарии +- 11.2: Уделяйте внимание обработке ошибок. + +### 12: `readme.md`: + +- 12.1: Поместите вначале `readme` ТЗ или **ссылку на него** - будет понятно о чем твой проект +- 12.2: Если задание на English, описание пиши также на English (то же самое относится к языку резюме: вакансия на English предполагает резюме на English) +- 12.3: Требуемые примеры `curl` не прячьте, а пишите здесь! Оптимально сделать **ссылку на `Swagger UI` с креденшелами для выполнения запросов** +- 12.4: Проверяют люди с опытом в Java: не надо писать инструкций, как устанавливать Java и Maven + +### 13: Git + +- 13.1: Должна быть история ваших комитов с внятными комментариями. Это смотрят. +- 13.2: Не комить служенбые файлы: логи, DB, настройки IDEA и пр., это сразу - уровень Junior. +- 13.3: Все служебные файлы должны быть в `.gitignore` + +## Проверка + +- Попробуй подергать свое API по всем типичным сценариям ТЗ! + - Удобно использовать? Можно сделать проще? Например, чтобы проголосовать за ресторан залогиненному юзеру, достаточно `restorauntId`. + - Сколько раз пришлось его вызвать API для типичного сценария (например посмотреть рестораны с едой на сегодня)? + - Сколько запросов к базе было сделано? Можно ли сократить (например с `FETCH/Graph` или через кэширование)? + - **Еще раз - проверь все запросы в Sawgger, смотри на формат запросов и данные в ответе. Все должно работать, есть все данные и нет ничего лишнего** +- 13.2: API ДОЛЖЕН соответствовать принципам REST (см. ссылки выше) +- 13.3: ОБЯЗАТЕЛЬНО: запустите `mvn test` - ошибок быть не должно +- 13.4: ОБЯЗАТЕЛЬНО: запустите приложение без всяких предварительных настроек (базы, переменных окружения, ..), лучше на другом компьютере. Приложение должно запускаться и работать! + +## Оценка +ТЗ очень скромное, не дает понимания, что хочет получить заказчик, именно поэтому моих комментариев к этому ТЗ больше на 2 порядка. Это реальное тестовое задание на работу. При оценке учитывается отсутствие грубых ляпов, простота и красота решения + его расширяемость, если понадобится дорабатывать приложение. Если практический опыт небольшой, еще раз очень рекомендую держаться как можно ближе к нашему коду на Spring Boot. +Тестовое задание дается для того, чтобы оценить вас, как программиста. Нужны ли вы компании или нет. Это умение спроектировать грамотную модель и API, придерживаясь принципов REST и без своих велосипедов, и ваш чистый красивый код. diff --git a/doc/lesson01.md b/doc/lesson01.md new file mode 100644 index 000000000..087ea3cdd --- /dev/null +++ b/doc/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) + + +###  Рефакторинг проекта + +#### 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` + +##  Разбор домашнего задания HW0: +###  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) + +###  2. Работа с git в IDEA. Реализация через цикл. +### ВНИМАНИЕ! Патчей `1_opt_2_HW0_cycles` и `1_opt_3_HW0_opt2` не будет в проекте! +Делаем в отдельной ветке (у меня `MealsUtil_opt`). Это варианты решений, которые не идут в `master` + + + +#### Apply 1_opt_2_HW0_cycles.patch + +###  Вопросы по HW0 + +> Почему не использовать в `TimeUtil` методы `isBefore/isAfter` ? + +это строгие (excluded) сравнения, а нам также нужно краевые значения + +> В `MealsUtil` у нас где-то есть ключевое слово `final`, где-то нет. В чем разница? + +Я участвовал в одном проекте, где `final` был обязательным (в сеттингах IDEA галочка стояла). Но это скорее исключение, чем правило в проектах java (в Java 8 вообще ввели эффективный final, те по факту). Во всех новомодных языках переменные final по умолчанию, а в java нужно помнить и везде добавлять, утомительно. Но если приучитесь - хуже не будет. Я обычно ставлю там, где важно по смыслу (если не забываю). + +###  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: + +###  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) +###  5. [Servlet API. Apache Tomcat. JSP](lesson01/tomcat_servlet_war.md) + +###  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) + + + +**Иногда антивирусы блокируют логирование (например Comodo). Если не работает и стоит антивирус- добавьте исключение.** + +> Изменения в проекте, которым могут встретиться в других видео: +> - убрал `LoggerWrapper` и логирую напрямую в логгер SLF4J. +> - удалил зависимости `jul-to-slf4j` и `jcl-over-slf4j`. Spring 5 напрямую использует `slf4j` без `common-logging` + +--------- + +##  Домашнее задание 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 | +
| ${user.email} | +${user.roles} | +${user.enabled} | +
+ * Comparing actual and expected objects via AssertJ
+ */
+public class MatcherFactory {
+ public static