From 572d0459e0c109ad051119757ef65d11b70f6302 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 18 Feb 2020 11:51:18 +0300 Subject: [PATCH 01/39] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 228b708b7094..ab4d97e44213 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,9 @@ Java Enterprise Online Project - Выполнить задание и залить на GitHub (commit + push) - Переключиться в основную ветку проекта master. +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Тех.задание: библия или допускаются изменения. Полуоткрытый интервал.](https://drive.google.com/file/d/123XyBYVeKLC3ZcRr_dUkwyvO9NC6WLkY/view?usp=sharing) +- [Типы промежутков](https://ru.wikipedia.org/wiki/Промежуток_(математика)) + ## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Домашнее задание HW0 ``` Реализовать метод `UserMealsUtil.filteredByCycles` через циклы (`forEach`): From 796d81b362a3e087d016e90e503fe208eb55740b Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 5 Mar 2020 23:56:35 +0300 Subject: [PATCH 02/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab4d97e44213..6b840eac3b03 100644 --- a/README.md +++ b/README.md @@ -175,7 +175,7 @@ Java Enterprise Online Project #### Java (базовые вещи) - Интуит. Программирование на Java - 1й урок MasterJava: Многопоточность -- Основы Java garbage collection +- [Основы Java garbage collection](http://web.archive.org/web/20180831013112/https://ggenikus.github.io/blog/2014/05/04/gc) - Размер Java объектов - Введение в Java Reflection API - Структуры данных в картинках From 80a3c742a574cfaf871982aeedb95fcd62722f66 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 26 Mar 2020 16:02:15 +0300 Subject: [PATCH 03/39] Update cv.md --- cv.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cv.md b/cv.md index a24d881fdeba..60860899fb3c 100644 --- a/cv.md +++ b/cv.md @@ -106,6 +106,8 @@ - Выдели самое главное путем опроса босса и важных коллег. Не распыляйся на мелочи. - [**5 вещей, которые разработчик должен сделать прежде чем попросить о помощи**](https://techrocks.ru/2018/07/16/5-things-a-developer-should-do-before-asking-for-help/) - [**Советы новичкам**](http://blog.csssr.ru/2016/09/19/how-to-be-a-beginner-developer) +- [ТОП-13 ошибок начинающего программиста](https://proglib.io/p/beginners-fails/) +- [25 ошибок начинающего программиста](https://habr.com/ru/post/413129/) - [Нетехнические навыки](https://tproger.ru/experts/softskills-for-job) ## [Отзывы по стажировке Topjava](https://vk.com/topic-74381644_30447246) From bee6ffcbffc764b82c1abd2fb4f6ff1087faa0a1 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 23 Apr 2020 14:05:13 +0300 Subject: [PATCH 04/39] Update ReleaseNotes.md --- ReleaseNotes.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index f4e7412eb816..f0cf1ed046f5 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,4 +1,20 @@ # TopJava Release Notes +### Topjava 19 +- Изменилась логика для интервалов времени (исключаем `endTime`) +- Заменил собственный `MessageUtil` велосипед на спринговый `MessageSourceAccessor` +- В ролях убрал префиксы `ROLE_` ([Role and GrantedAuthority](https://stackoverflow.com/a/19542316/548473)) +- Добавился удобный метод `int AbstractBaseEntity.id()` +- Фикс `Location` в `ProfileRestController.register` +- Фикс валидации `UniqueMailValidator` для REST update без `user.id` +- Заменил `jdbc.initLocation` на полный путь - IDEA не ругается +- В конфигурации `cargo-maven2-plugin` сделал [индивидуальный контекст приложения](https://stackoverflow.com/a/60797999/548473) +- Тесты + - Обновил даты еды на 2020г. + - Зарефакторил тесты сервисов на удаление - `NotFoundException` может бросаться при `delete()` + - В тестах контроллеров вернулся к реализации без обертки над `MockMvcRequestBuilders` + - Для `InMemory` тестов подключаю только `inmemory.xml` (добавил туда необходимую конфигурацию из `spring-app.xml`) + + ### Topjava 18 - В `ErrorType` добавил `HttpStatus status` From 2620c6f93e413d51271a5398e8545f3569036638 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sun, 10 May 2020 23:16:00 +0300 Subject: [PATCH 05/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b840eac3b03..f2777b677f7a 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Java Enterprise Online Project - без циклов по другим коллекциям - решение должно быть рабочим в общем случае (не только при запуске main) - через Stream API за 1 проход по исходному списку `meals.streem()` - - нельзя использовать внешние коллекции, не являющиеся частью коллектора или 2 раза проходить по исходному списку (его копиям). + - нельзя использовать внешние коллекции, не являющиеся частью коллектора или 2 раза проходить по исходному списку (в том числе модифицированному, например отфильтрованому). Т.е. в решении не должно быть 2 раза `meal.stream()` (в том числе неявно, в составных коллекторах) - возможно дополнительные проходы по частям списка From 3449156db3deb9fb8cb0d4c8d9bd5e8809729304 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sun, 10 May 2020 23:26:52 +0300 Subject: [PATCH 06/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f2777b677f7a..eece6c31d014 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Java Enterprise Online Project - без циклов по другим коллекциям - решение должно быть рабочим в общем случае (не только при запуске main) - через Stream API за 1 проход по исходному списку `meals.streem()` - - нельзя использовать внешние коллекции, не являющиеся частью коллектора или 2 раза проходить по исходному списку (в том числе модифицированному, например отфильтрованому). + - нельзя использовать внешние коллекции, не являющиеся частью коллектора или 2 раза проходить по исходному списку (в том числе модифицированному, например отфильтрованному). Т.е. в решении не должно быть 2 раза `meal.stream()` (в том числе неявно, в составных коллекторах) - возможно дополнительные проходы по частям списка From 052adf67944cf47671f94293014fbcfce7caa270 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 13 May 2020 22:03:35 +0300 Subject: [PATCH 07/39] Update cv.md --- cv.md | 1 + 1 file changed, 1 insertion(+) diff --git a/cv.md b/cv.md index 60860899fb3c..f765942cf700 100644 --- a/cv.md +++ b/cv.md @@ -20,6 +20,7 @@ ### Наши истории (делимся опытом и успехом) ### Тесты/задачи онлайн: +-[Interviewing: the most profitable skill you can learn](https://www.pramp.com) - [Java Programming Test](https://tests4geeks.com/java) - game: test Java skills - Codility lesson tests From 7c31a8ee0c7a6f87064a23a6d69f8b053a4b1cbf Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 13 May 2020 22:04:00 +0300 Subject: [PATCH 08/39] Update cv.md --- cv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cv.md b/cv.md index f765942cf700..51f5a7527ad9 100644 --- a/cv.md +++ b/cv.md @@ -20,7 +20,7 @@ ### Наши истории (делимся опытом и успехом) ### Тесты/задачи онлайн: --[Interviewing: the most profitable skill you can learn](https://www.pramp.com) +- [Interviewing: the most profitable skill you can learn](https://www.pramp.com) - [Java Programming Test](https://tests4geeks.com/java) - game: test Java skills - Codility lesson tests From 54f4ec0d6363ef814f3001f831b484dff60f3a7b Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 13 May 2020 22:05:03 +0300 Subject: [PATCH 09/39] Update cv.md --- cv.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cv.md b/cv.md index 51f5a7527ad9..a330bc3c71cb 100644 --- a/cv.md +++ b/cv.md @@ -20,7 +20,7 @@ ### Наши истории (делимся опытом и успехом) ### Тесты/задачи онлайн: -- [Interviewing: the most profitable skill you can learn](https://www.pramp.com) +- [Interviewing: the most profitable skill you can learn (pramp.com)](https://www.pramp.com/) - [Java Programming Test](https://tests4geeks.com/java) - game: test Java skills - Codility lesson tests @@ -29,7 +29,6 @@ - Sphere online judge - Codility programmers lessons - Hackerrank practice coding -- [Interviewing: the most profitable skill you can learn (pramp.com)](https://www.pramp.com/) - [start.interviewing.io](https://start.interviewing.io/) ## [Тестовое собеседование, самые спрашиваемые темы](http://javaops.ru/interview/test.html) From 5fe982c3fa982a20b6d31aee74dfc15bfff8ab62 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sun, 17 May 2020 23:21:23 +0300 Subject: [PATCH 10/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eece6c31d014..a91e1e814c5a 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ Java Enterprise Online Project ### Полезные ресурсы > ВНИМАНИЕ: -> - **ДЗ первого урока будет связано с [созданием небольшого CRUD приложения (в памяти, без DB) на JSP и сервлетах](http://danielniko.com/2012/04/17/simple-crud-using-jsp-servlet-and-mysql/)**. Введение будет, но предварительное знакомство не помешает. +> - **ДЗ первого урока будет связано с [созданием небольшого CRUD приложения (в памяти, без DB) на JSP и сервлетах](https://danielniko.wordpress.com/2012/04/17/simple-crud-using-jsp-servlet-and-mysql/)**. Введение будет, но предварительное знакомство не помешает. > - основы JavaSсript необходимы для понимания проекта, начиная с 8-го занятия! Все остальное - опционально. From c2180201f5095afdaf632c3e71681acf44d56014 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 19 May 2020 11:43:39 +0300 Subject: [PATCH 11/39] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a91e1e814c5a..040f70a6e44e 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,8 @@ Java Enterprise Online Project - Шпаргалка Java Stream API - Алексея Владыкин: Элементы функционального программирования в Java - Yakov Fain о новом в Java 8 -- stream.map vs forEach +- stream.map vs forEach Date: Tue, 19 May 2020 11:45:35 +0300 Subject: [PATCH 12/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 040f70a6e44e..f7cefcd90fb8 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ Java Enterprise Online Project Т.е. в решении не должно быть 2 раза `meal.stream()` (в том числе неявно, в составных коллекторах) - возможно дополнительные проходы по частям списка -- [Полное руководство по Java 8 Stream API в картинках и примерах](https://easyjava.ru/java/language/java-8-stream-api-chast-shestaya-sobstvennyj-kollektor/) +- [Java 8 Stream API, часть шестая: собственный коллектор](https://easyjava.ru/java/language/java-8-stream-api-chast-shestaya-sobstvennyj-kollektor) - [Руководство по Java 8 Stream API: Collector](https://annimon.com/article/2778#collector) ### Замечания по использованию Stream API: From 3b91874e6df53a7d7fcebb7efa8fc0bf40ad2be9 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 19 May 2020 11:46:05 +0300 Subject: [PATCH 13/39] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index f7cefcd90fb8..6a58dbce5545 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,6 @@ Java Enterprise Online Project - нельзя использовать внешние коллекции, не являющиеся частью коллектора или 2 раза проходить по исходному списку (в том числе модифицированному, например отфильтрованному). Т.е. в решении не должно быть 2 раза `meal.stream()` (в том числе неявно, в составных коллекторах) - возможно дополнительные проходы по частям списка - - [Java 8 Stream API, часть шестая: собственный коллектор](https://easyjava.ru/java/language/java-8-stream-api-chast-shestaya-sobstvennyj-kollektor) - [Руководство по Java 8 Stream API: Collector](https://annimon.com/article/2778#collector) From 18f0374c537cd28f46b4e1db8f98fc5088f8ac9a Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 19 May 2020 11:47:22 +0300 Subject: [PATCH 14/39] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6a58dbce5545..d3a4c1e67cec 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,8 @@ Java Enterprise Online Project - нельзя использовать внешние коллекции, не являющиеся частью коллектора или 2 раза проходить по исходному списку (в том числе модифицированному, например отфильтрованному). Т.е. в решении не должно быть 2 раза `meal.stream()` (в том числе неявно, в составных коллекторах) - возможно дополнительные проходы по частям списка + +Ресурсы: - [Java 8 Stream API, часть шестая: собственный коллектор](https://easyjava.ru/java/language/java-8-stream-api-chast-shestaya-sobstvennyj-kollektor) - [Руководство по Java 8 Stream API: Collector](https://annimon.com/article/2778#collector) From ba240e81eca53c90ca40ec4bfa771393bc8ef71e Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 20 May 2020 22:16:40 +0300 Subject: [PATCH 15/39] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d3a4c1e67cec..8755b22281f5 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,8 @@ Java Enterprise Online Project - [Git - для новичков](https://www.youtube.com/watch?list=PLY4rE9dstrJyTdVJpv7FibSaXB4BHPInb&v=PEKN8NtBDQ0) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. Работа с проектом (выполнять инструкции) -**ВНИМАНИЕ: выбирайте для проекта простой пусть без пробелов и русских букв, например (Windows) `c:\projects\topjava\`. Иначе впоследствии будут проблемы** +- **ВНИМАНИЕ: выбирайте для проекта простой пусть без пробелов и русских букв, например (Windows) `c:\projects\topjava\`. Иначе впоследствии будут проблемы** +- **Плагин уже Git Intergation не требуется и вкладку `Version control` в IDEA переименовали в `Git`** ### Патч [prepare_to_HW0.patch](https://drive.google.com/file/d/1LNPpu9OkuCpfpD8ZJHO-o0vwu49p2i5M) (скачать и положить в каталог вашего проекта) > Проект постоянно улучшается, поэтому видео иногда отличается от кода проекта. Изменения указываю после видео: From 7eb4a67c93f47950a420d561b7de6956c1a9eb1b Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sat, 23 May 2020 19:10:30 +0300 Subject: [PATCH 16/39] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8755b22281f5..777992140667 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ Java Enterprise Online Project - Git Overview - [Основы Git за 20 минут](https://www.youtube.com/watch?v=TMeZGvtQnT8) - [Git - для новичков](https://www.youtube.com/watch?list=PLY4rE9dstrJyTdVJpv7FibSaXB4BHPInb&v=PEKN8NtBDQ0) + - [Руководство по написанию комментариев в коммитах](https://techrocks.ru/2019/12/02/writing-good-commit-messages) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. Работа с проектом (выполнять инструкции) - **ВНИМАНИЕ: выбирайте для проекта простой пусть без пробелов и русских букв, например (Windows) `c:\projects\topjava\`. Иначе впоследствии будут проблемы** From efd86a06ca26f316d5a38a58de6b887789c7cd36 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sun, 24 May 2020 01:00:39 +0300 Subject: [PATCH 17/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 777992140667..754e9d2cdf25 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ Java Enterprise Online Project - 10: `System.out.println` нельзя делать нигде, кроме как в `main`. Позже введем логирование. - 11: Результаты, возвращаемые `UserMealsUtil.filteredByStreams` мы будем использовать [в нашем приложении](http://topjava.herokuapp.com/) для фильтрации по времени и отображения еды правильным цветом. - 12: Обращайте внимание на комментарии к вашим коммитам в git. Они должны быть короткие и информативные (лучше на english) -- 13: Не полагайтесь в решении на то, что список будет подаваться отсортированным. Такого условия нет. +- 13: Не полагайтесь в решении на то, что список еды будет подаваться отсортированным. Такого условия нет. ----- ## [Пример 7-го занятия онлайн стажировки, несколько видео открыто](https://github.com/JavaOPs/topjava/blob/master/doc/lesson07.md) From 628eb10dea9635fd23acb08b6477f897d14426d8 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sun, 24 May 2020 13:32:50 +0300 Subject: [PATCH 18/39] Update graduation.md --- graduation.md | 1 + 1 file changed, 1 insertion(+) diff --git a/graduation.md b/graduation.md index 6e4af3e023cc..c1cb45c337b2 100644 --- a/graduation.md +++ b/graduation.md @@ -66,6 +66,7 @@ _Антуан де Сент-Экзюпери_ - 21: Проверьте, станет ли код проще с `@AuthenticationPrincipal` (урок 11, Доступ к AuthorizedUser). - 22: Не размещайте логику приложения и преобразования в TO в слое доступа к DB - 23: Если используете кэширование, **тщательно продумайте, что надо кэшировать (самые частые запросы)**, а что нет (большие или редкозапрашиваемые данные)! +- 24: Если задание на English, `readme.md` тоже пишите на English. То же самое относится к языку резюме: вакансия на English предполагает ваше резюме на English. ## Попробуйте подергать свое API по всем типичным сценариям ТЗ! - Удобно использовать? Можно сделать проще? Например чтобы проголосовать за ресторан залогиненному юзеру достаточно `restorauntId`. From c7a9d42c53c720477944de607b83e722ef3fb750 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sun, 24 May 2020 13:37:51 +0300 Subject: [PATCH 19/39] Update graduation.md --- graduation.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/graduation.md b/graduation.md index c1cb45c337b2..60fdff4b9d1d 100644 --- a/graduation.md +++ b/graduation.md @@ -66,7 +66,10 @@ _Антуан де Сент-Экзюпери_ - 21: Проверьте, станет ли код проще с `@AuthenticationPrincipal` (урок 11, Доступ к AuthorizedUser). - 22: Не размещайте логику приложения и преобразования в TO в слое доступа к DB - 23: Если используете кэширование, **тщательно продумайте, что надо кэшировать (самые частые запросы)**, а что нет (большие или редкозапрашиваемые данные)! -- 24: Если задание на English, `readme.md` тоже пишите на English. То же самое относится к языку резюме: вакансия на English предполагает ваше резюме на English. +- 24: `readme.md`: + - Если задание на English, описание пишите также на English (то же самое относится к языку резюме: вакансия на English предполагает ваше резюме на English) + - Требуемые примеры `curl` не прячте- пишите здесь! + - Проверяют люди с опытом в Java: не надо писать инструкций, как устанавливать Java и Maven:) ## Попробуйте подергать свое API по всем типичным сценариям ТЗ! - Удобно использовать? Можно сделать проще? Например чтобы проголосовать за ресторан залогиненному юзеру достаточно `restorauntId`. From 7d0145036d3e3e1c69fd053cb6195379aaf9c9ff Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 27 May 2020 13:45:01 +0300 Subject: [PATCH 20/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 754e9d2cdf25..379464cf4f6b 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ Java Enterprise Online Project - [Сергей Куксенко — Stream API, часть 1](https://www.youtube.com/watch?v=O8oN4KSZEXE) - [Сергей Куксенко — Stream API, часть 2](https://www.youtube.com/watch?v=i0Jr2l3jrDA) -### Optional 2 (+5 бонусов) +### Optional 2 (+5 бонусов, только после выполнения базового и Optional задания!) Сделать реализацию со сложностью O(N) (обратите внимание на п.13 замечаний): - циклом за 1 проход по `List` - без циклов по другим коллекциям From 6464f3cab8aa6fdfd9732d83ee15e972dc9809b7 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 27 May 2020 16:02:09 +0300 Subject: [PATCH 21/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 379464cf4f6b..39f4548d8b6f 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Java Enterprise Online Project ### Optional 2 (+5 бонусов, только после выполнения базового и Optional задания!) Сделать реализацию со сложностью O(N) (обратите внимание на п.13 замечаний): - циклом за 1 проход по `List` - - без циклов по другим коллекциям + - без циклов по другим коллекциям (к ним также относим методы коллекций `addAll()/removeAll()`) - решение должно быть рабочим в общем случае (не только при запуске main) - через Stream API за 1 проход по исходному списку `meals.streem()` - нельзя использовать внешние коллекции, не являющиеся частью коллектора или 2 раза проходить по исходному списку (в том числе модифицированному, например отфильтрованному). From 8f2c0376054663ce5c73dcbb68a7a2d3cdab6298 Mon Sep 17 00:00:00 2001 From: JavaOPs Date: Thu, 28 May 2020 11:32:08 +0300 Subject: [PATCH 22/39] Update graduate --- graduation.md | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/graduation.md b/graduation.md index 60fdff4b9d1d..af0f4f74078c 100644 --- a/graduation.md +++ b/graduation.md @@ -26,7 +26,7 @@ P.P.S.: Asume that your API will be used by a frontend developer to build fronte ----------------------------- ### ![error](https://cloud.githubusercontent.com/assets/13649199/13672935/ef09ec1e-e6e7-11e5-9f79-d1641c05cbe6.png) Рекомендации -- Если ты закончил [стажировку Topjava](http://javaops.ru/reg/topjava/grd), **cделай новый проект и добавляй туда из Topjava только то что нужно!** Локализация, типы ошибок, BeanMatcher, Json View, излишние делегирования и наследования - **не нужны!** +- **Сделай новый проект и добавляй туда из Topjava только то что нужно! Локализация, типы ошибок, BeanMatcher, Json View, излишние делегирования и наследования - не нужны!** - **API продумывай с точки зрения не программиста и объектов, а с точки зрения того, кто им будет пользоваться (frontend)** - **Сначала сделай основной сценарий по ТЗ. Все остальное (если очень хочется, 3 раза подумай) - потом.** @@ -45,27 +45,36 @@ _Антуан де Сент-Экзюпери_ - 5.2 НЕ надо делать абстрактных контроллеров на всякий случай. - 5.3 НЕ надо делать **классов репозиториев и сервисов**, если там нет ничего, кроме делегирования. - 5.4 Из потребностей приложения (которую надо самим придумать) реализовывать только очевидные сценарии. Те.- НИЧЕГО ЛИШНЕГО. -- 6: базу лучше взять без установки (H2 или HSQLDB). Ваше приложение должно сразу запуститься, **без всяких настроек и переменных окружения** +- 6: База Данных + - берите без установки (H2 или HSQLDB). Одну!! Ваше приложение должно сразу запуститься, **без всяких настроек и переменных окружения** + - сделайте индексы к таблицам. Попробуйте обеспечит UNIQUE (один голос пользователя в день, один уникальный пункт меню в день). Следите за порядком полей в индексе. + - **историю еды и голосований сделать НУЖНО! Есть базовые вещи, которые закладываются в архитектуру приложения и неочевидные доработки к ТЗ, которых лучше не делать.** - 7: по возможности сделать JUnit тесты - 8: уделяйте внимание обработке ошибок -- 9: далаем REST API в соответствии с концепцией REST - - [15 тривиальных фактов о правильной работе с протоколом HTTP](https://habrahabr.ru/company/yandex/blog/265569/) - - 10 Best Practices for Better RESTful API +- 9: далаем REST API в соответствии с концепцией REST (url в общем имеют вид`{ресурс}/{id_ресурсa}[/{подресурс}/{id_подресурсa}][параметры]`) + - **[15 тривиальных фактов о правильной работе с протоколом HTTP](https://habrahabr.ru/company/yandex/blog/265569/)** + - **10 Best Practices for Better RESTful API** - [REST resource hierarchy](https://stackoverflow.com/questions/20951419/what-are-best-practices-for-rest-nested-resources) - 10: не смешивайте TO и Entity вместе. Лучше всего, если они будут независимыми друг от друга. -- 11: если приложению в объекте требуется только его id, используйте reference (как мы при сохранении еды вставляем туда юзера) -- 12: [Use for money in java app](http://stackoverflow.com/a/43051227/548473) -- 13: **Историю еды и голосований сделать НУЖНО! Есть базовые вещи, которые закладываются в архитектуру приложения и неочевидные доработки к ТЗ, которых лучше не делать.** -- 14: Еще раз про [hashCode/equals в Entity](https://stackoverflow.com/questions/5031614/the-jpa-hashcode-equals-dilemma): не делайте сравнение по полям! -- 15: Название пакетов, имен классов для `model/to/web` достаточно стандартные (например `model/domain`). НЕ надо придумывать своих собственных правил. +- 11: не размещайте логику приложения и преобразования в TO в слое доступа к DB +- 12: если приложению в объекте требуется только его id, используйте reference (как мы при сохранении еды вставляем туда юзера) +- 13: [Use for money in java app](http://stackoverflow.com/a/43051227/548473) +- 14: еще раз про [hashCode/equals в Entity](https://stackoverflow.com/questions/5031614/the-jpa-hashcode-equals-dilemma): не делайте сравнение по полям! +- 15: название пакетов, имен классов для `model/to/web` достаточно стандартные (например `model/domain`). НЕ надо придумывать своих собственных правил. - 16: **Используйте DATA-JPA** (можно без лишней делегации, напрямую из сервиса/контроллера дергать Repository). -- 17: В DATA-JPA 2.x используются `Optional`. Попробуйте работать с ними, это безопасный способ работать с null значениями (используйте `orElseThrow`). -- 18: На topjava мы смотрели разные варианты использования, тут делаем максимально просто. С TO многие вещи упрощаются. -- 19: Проверьте, не торчат ли из кода учебные уши topjava, типа `ProfileRestController.testUTF()`, `AbstractServiceTest.printResult()` или закомментированные `JdbcTemplate`. Назначение этого проекта совсем другое. +- 17: в DATA-JPA 2.x используются `Optional`. Попробуйте работать с ними, это безопасный способ работать с null значениями (используйте `orElseThrow`). +- 18: на topjava мы смотрели разные варианты использования, тут делаем максимально просто. С TO многие вещи упрощаются. +- 19: проверьте, не торчат ли из кода учебные уши topjava, типа `ProfileRestController.testUTF()`, `AbstractServiceTest.printResult()` или закомментированные `JdbcTemplate`. Назначение этого проекта совсем другое. - 20: ORM работает с объектами. [В простейших случаях fk_id как поля допустимы](https://stackoverflow.com/questions/6311776/hibernate-foreign-keys-instead-of-entities), но при этом JPA их уже никак не обрабатывает и не используйте их вместе с объектами. Ссылка на stackoverwrflow в коде обязательна! -- 21: Проверьте, станет ли код проще с `@AuthenticationPrincipal` (урок 11, Доступ к AuthorizedUser). -- 22: Не размещайте логику приложения и преобразования в TO в слое доступа к DB -- 23: Если используете кэширование, **тщательно продумайте, что надо кэшировать (самые частые запросы)**, а что нет (большие или редкозапрашиваемые данные)! +- 21: проверьте, станет ли код проще с `@AuthenticationPrincipal` (урок 11, Доступ к AuthorizedUser). +- 22: Кэширование + - необязательно, но желательно + - **тщательно продумайте, что надо кэшировать (самые частые запросы)**, а что нет (большие или редкозапрашиваемые данные)! + - проверьте соответствие ключей к кэшу (параметры кэшируемого метода) с конфигурацией (например в singleNonExpiryCache, heap=1 в кэше может содержаться только ОДНО значение). +- 23: Валидация + - желательна + - одних аннотаций недостаточно. Должны быть `@Valid/@Validation` + - проверяйте входные данные при `create/update` в контроллерах! В TopJava это `ValidationUtil.checkNew()/assureIdConsistent()` - 24: `readme.md`: - Если задание на English, описание пишите также на English (то же самое относится к языку резюме: вакансия на English предполагает ваше резюме на English) - Требуемые примеры `curl` не прячте- пишите здесь! From 79efab669a610cb09e16621ff25d9240046911cf Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sun, 31 May 2020 23:26:28 +0300 Subject: [PATCH 23/39] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 39f4548d8b6f..c0d69a45fe7e 100644 --- a/README.md +++ b/README.md @@ -119,12 +119,12 @@ Java Enterprise Online Project ### Optional 2 (+5 бонусов, только после выполнения базового и Optional задания!) Сделать реализацию со сложностью O(N) (обратите внимание на п.13 замечаний): - циклом за 1 проход по `List` - - без циклов по другим коллекциям (к ним также относим методы коллекций `addAll()/removeAll()`) - - решение должно быть рабочим в общем случае (не только при запуске main) + - без циклов по другим коллекциям/массивам (к ним также относим методы коллекций `addAll()/removeAll()`) + - решение должно быть рабочим в общем случае (работать в приложении с многими пользователями, не только при запуске main) - через Stream API за 1 проход по исходному списку `meals.streem()` - - нельзя использовать внешние коллекции, не являющиеся частью коллектора или 2 раза проходить по исходному списку (в том числе модифицированному, например отфильтрованному). - Т.е. в решении не должно быть 2 раза `meal.stream()` (в том числе неявно, в составных коллекторах) - - возможно дополнительные проходы по частям списка + - нельзя использовать внешние коллекции, не являющиеся частью коллектора + - возможно дополнительные проходы по частям списка, при этом превышение должно считаться один раз для всего подсписка. Те например нельзя разбить список на на 2 подсписка с четными и нечетными датами и затем их объединить, с подсчетом превышения для каждого элемента. + Ресурсы: - [Java 8 Stream API, часть шестая: собственный коллектор](https://easyjava.ru/java/language/java-8-stream-api-chast-shestaya-sobstvennyj-kollektor) From 7664bb38066ab8843696b719a8bdc13a3e138e07 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 4 Jun 2020 18:14:35 +0300 Subject: [PATCH 24/39] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c0d69a45fe7e..f2020bbfcd53 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ Java Enterprise Online Project - решение должно быть рабочим в общем случае (работать в приложении с многими пользователями, не только при запуске main) - через Stream API за 1 проход по исходному списку `meals.streem()` - нельзя использовать внешние коллекции, не являющиеся частью коллектора + - нельзя 2 раза проходить по исходному списку (в том числе его отфильтрованной копии) - возможно дополнительные проходы по частям списка, при этом превышение должно считаться один раз для всего подсписка. Те например нельзя разбить список на на 2 подсписка с четными и нечетными датами и затем их объединить, с подсчетом превышения для каждого элемента. From 2cf32713038aae3a29ed2bb3f49ce8ca75ac9068 Mon Sep 17 00:00:00 2001 From: "admin@javaops.ru" Date: Thu, 4 Jun 2020 18:27:09 +0300 Subject: [PATCH 25/39] Update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f2020bbfcd53..638048568128 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Java Enterprise Online Project > - в `UserMeals/UserMealWithExcess` поля изменились на `private` > - обновил данные `UserMealsUtil.meals` и переименовал некоторые пременные, поля и методы > - добавил `UserMealWithExcess.toString()` и метод для выполнения _Optional домашнего задания_ - +> - метод фильтрации в `TimeUtil` переименовали в `isBetweenHalfOpen` (также изменилась логика сравнения - `startTime` включается в интервал) ## Инструкция по шагам (из видео): - Установить ПО (git, JDK8, IntelliJ IDEA, Maven) From 4331b732f57e2bbef144489026f07581d1fa0d6f Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 17 Jun 2020 15:35:54 +0300 Subject: [PATCH 26/39] Update graduation.md --- graduation.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/graduation.md b/graduation.md index af0f4f74078c..4580cd250957 100644 --- a/graduation.md +++ b/graduation.md @@ -67,15 +67,16 @@ _Антуан де Сент-Экзюпери_ - 19: проверьте, не торчат ли из кода учебные уши topjava, типа `ProfileRestController.testUTF()`, `AbstractServiceTest.printResult()` или закомментированные `JdbcTemplate`. Назначение этого проекта совсем другое. - 20: ORM работает с объектами. [В простейших случаях fk_id как поля допустимы](https://stackoverflow.com/questions/6311776/hibernate-foreign-keys-instead-of-entities), но при этом JPA их уже никак не обрабатывает и не используйте их вместе с объектами. Ссылка на stackoverwrflow в коде обязательна! - 21: проверьте, станет ли код проще с `@AuthenticationPrincipal` (урок 11, Доступ к AuthorizedUser). -- 22: Кэширование +- 22: обновление в базе делается через `update`, даже если `delete/insert` сократит java код на несколько строк +- 23: Кэширование - необязательно, но желательно - **тщательно продумайте, что надо кэшировать (самые частые запросы)**, а что нет (большие или редкозапрашиваемые данные)! - проверьте соответствие ключей к кэшу (параметры кэшируемого метода) с конфигурацией (например в singleNonExpiryCache, heap=1 в кэше может содержаться только ОДНО значение). -- 23: Валидация +- 24: Валидация - желательна - одних аннотаций недостаточно. Должны быть `@Valid/@Validation` - проверяйте входные данные при `create/update` в контроллерах! В TopJava это `ValidationUtil.checkNew()/assureIdConsistent()` -- 24: `readme.md`: +- 25: `readme.md`: - Если задание на English, описание пишите также на English (то же самое относится к языку резюме: вакансия на English предполагает ваше резюме на English) - Требуемые примеры `curl` не прячте- пишите здесь! - Проверяют люди с опытом в Java: не надо писать инструкций, как устанавливать Java и Maven:) From 64590f1ca576fbc18c743227f61ca33eb21c14f4 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 17 Jun 2020 15:44:52 +0300 Subject: [PATCH 27/39] Update graduation.md --- graduation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graduation.md b/graduation.md index 4580cd250957..3c8d83d87b49 100644 --- a/graduation.md +++ b/graduation.md @@ -39,7 +39,7 @@ _Антуан де Сент-Экзюпери_ - 1: **читаем ТЗ ОЧЕНЬ внимательно, НЕ надо ничего своего туда домысливать и творчески изменять** - 2: **тщательно считайте количество обращений в базу на каждый запрос. Особенно при запросах от юзеров, которых очень много! Также на сложность запросов от них, чтобы не положить базу** - 3: **тщательно считайте количество запросов в вашем API для отображения нужной информации** -- 4: **учитывайте, что пользователей может быть ооочень много, а админов- мало** +- 4: учитывайте, что **пользователей может быть ОООЧЕНЬ много, а админов - МАЛО** - 5: в проекте (и тестовом задании на работу) в отличие от нашего учебного topjava оставляйте только необходимый для работы приложения код, ничего лишнего: - 5.1 НЕ надо делать разные профили базы и работы с ней. - 5.2 НЕ надо делать абстрактных контроллеров на всякий случай. From 3823848bb585a052d04d6f55c4654e8a6c25b0ea Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sun, 20 Sep 2020 15:47:52 +0300 Subject: [PATCH 28/39] Update graduation.md --- graduation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graduation.md b/graduation.md index 3c8d83d87b49..7dd13808b7e1 100644 --- a/graduation.md +++ b/graduation.md @@ -37,7 +37,7 @@ P.P.S.: Asume that your API will be used by a frontend developer to build fronte _Антуан де Сент-Экзюпери_ - 1: **читаем ТЗ ОЧЕНЬ внимательно, НЕ надо ничего своего туда домысливать и творчески изменять** -- 2: **тщательно считайте количество обращений в базу на каждый запрос. Особенно при запросах от юзеров, которых очень много! Также на сложность запросов от них, чтобы не положить базу** +- 2: **тщательно считайте количество обращений в базу на каждый запрос. Особенно при запросах от юзеров, которых очень много! Также на сложность запросов от них, чтобы не положить базу**. Самое худшее в коде - обращение в базу в цикле. - 3: **тщательно считайте количество запросов в вашем API для отображения нужной информации** - 4: учитывайте, что **пользователей может быть ОООЧЕНЬ много, а админов - МАЛО** - 5: в проекте (и тестовом задании на работу) в отличие от нашего учебного topjava оставляйте только необходимый для работы приложения код, ничего лишнего: From f2d884f882826c78d00020049f42a5d81cf1c3ae Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sun, 20 Sep 2020 15:49:23 +0300 Subject: [PATCH 29/39] Update graduation.md --- graduation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graduation.md b/graduation.md index 7dd13808b7e1..34809fc454db 100644 --- a/graduation.md +++ b/graduation.md @@ -61,7 +61,7 @@ _Антуан де Сент-Экзюпери_ - 13: [Use for money in java app](http://stackoverflow.com/a/43051227/548473) - 14: еще раз про [hashCode/equals в Entity](https://stackoverflow.com/questions/5031614/the-jpa-hashcode-equals-dilemma): не делайте сравнение по полям! - 15: название пакетов, имен классов для `model/to/web` достаточно стандартные (например `model/domain`). НЕ надо придумывать своих собственных правил. -- 16: **Используйте DATA-JPA** (можно без лишней делегации, напрямую из сервиса/контроллера дергать Repository). +- 16: **Используйте DATA-JPA** (сделайте без лишней делегации, напрямую из сервиса/контроллера дергать Repository). - 17: в DATA-JPA 2.x используются `Optional`. Попробуйте работать с ними, это безопасный способ работать с null значениями (используйте `orElseThrow`). - 18: на topjava мы смотрели разные варианты использования, тут делаем максимально просто. С TO многие вещи упрощаются. - 19: проверьте, не торчат ли из кода учебные уши topjava, типа `ProfileRestController.testUTF()`, `AbstractServiceTest.printResult()` или закомментированные `JdbcTemplate`. Назначение этого проекта совсем другое. From fd2d8522aab499c9aae6d12832b91d8f48bd68cb Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sun, 20 Sep 2020 16:46:23 +0300 Subject: [PATCH 30/39] Update graduation.md --- graduation.md | 1 + 1 file changed, 1 insertion(+) diff --git a/graduation.md b/graduation.md index 34809fc454db..d947b113c79f 100644 --- a/graduation.md +++ b/graduation.md @@ -49,6 +49,7 @@ _Антуан де Сент-Экзюпери_ - берите без установки (H2 или HSQLDB). Одну!! Ваше приложение должно сразу запуститься, **без всяких настроек и переменных окружения** - сделайте индексы к таблицам. Попробуйте обеспечит UNIQUE (один голос пользователя в день, один уникальный пункт меню в день). Следите за порядком полей в индексе. - **историю еды и голосований сделать НУЖНО! Есть базовые вещи, которые закладываются в архитектуру приложения и неочевидные доработки к ТЗ, которых лучше не делать.** + - при популировании добавте записи за сегодняшний день - now(), чтобы всегда были актуальные исходные данные - 7: по возможности сделать JUnit тесты - 8: уделяйте внимание обработке ошибок - 9: далаем REST API в соответствии с концепцией REST (url в общем имеют вид`{ресурс}/{id_ресурсa}[/{подресурс}/{id_подресурсa}][параметры]`) From b2b9a19dbf33f24e9a1e532c6d74a498328370e1 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Sun, 20 Sep 2020 22:20:46 +0300 Subject: [PATCH 31/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 638048568128..38831adc6f29 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ Java Enterprise Online Project - решение должно быть рабочим в общем случае (работать в приложении с многими пользователями, не только при запуске main) - через Stream API за 1 проход по исходному списку `meals.streem()` - нельзя использовать внешние коллекции, не являющиеся частью коллектора - - нельзя 2 раза проходить по исходному списку (в том числе его отфильтрованной копии) + - нельзя 2 раза проходить по исходному списку (в том числе его отфильтрованной или преобразованной копии) - возможно дополнительные проходы по частям списка, при этом превышение должно считаться один раз для всего подсписка. Те например нельзя разбить список на на 2 подсписка с четными и нечетными датами и затем их объединить, с подсчетом превышения для каждого элемента. From 7c7e37e548ddc01369ff9448a1a9d390be387141 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Mon, 21 Sep 2020 17:37:53 +0300 Subject: [PATCH 32/39] Update graduation.md --- graduation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graduation.md b/graduation.md index d947b113c79f..208ee73c69cb 100644 --- a/graduation.md +++ b/graduation.md @@ -76,7 +76,7 @@ _Антуан де Сент-Экзюпери_ - 24: Валидация - желательна - одних аннотаций недостаточно. Должны быть `@Valid/@Validation` - - проверяйте входные данные при `create/update` в контроллерах! В TopJava это `ValidationUtil.checkNew()/assureIdConsistent()` + - проверяйте входные данные при `create/update` **в контроллерах!** В TopJava это `ValidationUtil.checkNew()/assureIdConsistent()` - 25: `readme.md`: - Если задание на English, описание пишите также на English (то же самое относится к языку резюме: вакансия на English предполагает ваше резюме на English) - Требуемые примеры `curl` не прячте- пишите здесь! From 9c995f9b94680892e8e805462de14e1797aebc29 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 24 Sep 2020 14:26:51 +0300 Subject: [PATCH 33/39] Update graduation.md --- graduation.md | 1 + 1 file changed, 1 insertion(+) diff --git a/graduation.md b/graduation.md index 208ee73c69cb..a4468a0f8ec9 100644 --- a/graduation.md +++ b/graduation.md @@ -50,6 +50,7 @@ _Антуан де Сент-Экзюпери_ - сделайте индексы к таблицам. Попробуйте обеспечит UNIQUE (один голос пользователя в день, один уникальный пункт меню в день). Следите за порядком полей в индексе. - **историю еды и голосований сделать НУЖНО! Есть базовые вещи, которые закладываются в архитектуру приложения и неочевидные доработки к ТЗ, которых лучше не делать.** - при популировании добавте записи за сегодняшний день - now(), чтобы всегда были актуальные исходные данные + - таблицы обычно именуются в единственном числе. Исключение - users, т. к. user - зарезервированное слово. `date`/`timestamp` - зарезервированное слово, лучше избегать их при именовании - 7: по возможности сделать JUnit тесты - 8: уделяйте внимание обработке ошибок - 9: далаем REST API в соответствии с концепцией REST (url в общем имеют вид`{ресурс}/{id_ресурсa}[/{подресурс}/{id_подресурсa}][параметры]`) From 00424a0eaa980dcfcacc6bc6a9bef81b4472b983 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Mon, 28 Sep 2020 22:45:15 +0300 Subject: [PATCH 34/39] Update ReleaseNotes.md --- ReleaseNotes.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index f0cf1ed046f5..bf225b9b0647 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,4 +1,15 @@ # TopJava Release Notes + +### Topjava 20 +- мигрировали на JDK 14 +- в `@SafeHtml` запрещаем весь html (`whitelistType = NONE`) +- в API добавили `/users/{id}/with-meals` (см. [двунаправленные отношения](https://www.codeflow.site/ru/article/jackson-bidirectional-relationships-and-infinite-recursion)) +- в js убрал объект контекст, передаю 3-мя параметрами +- в UI контроллерах убрал префикс `ajax` +- из тестов сервисов убрал `repository`. При проверке через `assertThrows` он не требуется +- в `TestMatcher` сценарии сравнения сделал параметризируемыми (паттерн стратегия) +- добавил `UserTestData.USER_WITH_MEALS_MATCHER` (проверки пользователя сразу с едой) и константу id `NOT_FOUND` + ### Topjava 19 - Изменилась логика для интервалов времени (исключаем `endTime`) - Заменил собственный `MessageUtil` велосипед на спринговый `MessageSourceAccessor` From 61cd81364ee3d2247ef9a53958d23d21a8671f6b Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Mon, 28 Sep 2020 22:50:02 +0300 Subject: [PATCH 35/39] Update ReleaseNotes.md --- ReleaseNotes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index bf225b9b0647..b102200d7ac1 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -3,11 +3,11 @@ ### Topjava 20 - мигрировали на JDK 14 - в `@SafeHtml` запрещаем весь html (`whitelistType = NONE`) -- в API добавили `/users/{id}/with-meals` (см. [двунаправленные отношения](https://www.codeflow.site/ru/article/jackson-bidirectional-relationships-and-infinite-recursion)) -- в js убрал объект контекст, передаю 3-мя параметрами +- в `topjava.common.js` в `makeEditable()` вместо объекта контекст передаю 3 параметра - в UI контроллерах убрал префикс `ajax` - из тестов сервисов убрал `repository`. При проверке через `assertThrows` он не требуется - в `TestMatcher` сценарии сравнения сделал параметризируемыми (паттерн стратегия) +- в API добавили `/users/{id}/with-meals` (см. [двунаправленные отношения](https://www.codeflow.site/ru/article/jackson-bidirectional-relationships-and-infinite-recursion)) - добавил `UserTestData.USER_WITH_MEALS_MATCHER` (проверки пользователя сразу с едой) и константу id `NOT_FOUND` ### Topjava 19 From 91841cb912cc4ff8711016f34a166cfe94789469 Mon Sep 17 00:00:00 2001 From: "admin@javaops.ru" Date: Thu, 29 Oct 2020 14:10:49 +0300 Subject: [PATCH 36/39] fix grammar --- ReleaseNotes.md | 2 +- description.md | 125 +++++++++++++++++++++++------------------------- graduation.md | 40 ++++++++-------- 3 files changed, 81 insertions(+), 86 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index b102200d7ac1..65a0c209f4c1 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -29,7 +29,7 @@ ### Topjava 18 - В `ErrorType` добавил `HttpStatus status` -- В PostgreSQL обнаружилась бага: граничное значение `0:00` из за ошибок округления попадает в предыдущий интервал. +- В PostgreSQL обнаружилась бага: граничное значение `0:00` из-за ошибок округления попадает в предыдущий интервал. Мораль: всегда в тестах проверяйте граничные значения. Добавил этот случай в тестовые данные. - Изменил `MealRepository.getBetween` (принимаю `@Nullable LocalDate`). Изменились реализации. - Выделил метод `UserService.prepareAndSave` diff --git a/description.md b/description.md index d2448ca99e57..0619c6d9516d 100644 --- a/description.md +++ b/description.md @@ -1,77 +1,72 @@ #### Разработка полнофункционального 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. -- Основное внимание будет уделяться способам решения многочисленных проблем разработки в Spring/JPA, а также структурному (красивому и надежному) java кодированию и архитектуре приложения. -- Каждая итерация проекта закрепляется домашним заданием по реализации схожей функциональности. Следующее занятие начинается с разбора домашних заданий. -- Большое внимание уделяется тестированию кода: в проекте более 100 JUnit тестов. -- Несмотря на относительно небольшой размер, приложение разрабатывается с нуля как большой проект (например мы используем кэш 2-го уровня Hibernate, настраиваем Jackson для работы с ленивой загрузкой +- Основное внимание будет уделяться способам решения многочисленных проблем разработки в Spring/JPA, а также структурному (красивому и надежному) java кодированию и архитектуре приложения. +- Каждая итерация проекта закрепляется домашним заданием по реализации схожей функциональности. Следующее занятие начинается с разбора домашних заданий. +- Большое внимание уделяется тестированию кода: в проекте более 100 JUnit тестов. +- Несмотря на относительно небольшой размер, приложение разрабатывается с нуля как большой проект (например, мы используем кэш 2-го уровня Hibernate, настраиваем Jackson для работы с ленивой загрузкой Hibernate, делаем конверторы для типов LocalDateTime (Java 8 time API). - Разбираются архитектурные паттерны: слои приложения и как правильно разбивать логику по слоям, когда нужно применять Data Transfer Object. - Т.е на выходе получается не учебный проект, а хорошо маштабируемый шаблон для большого проекта на всех пройденных технологиях. -- Большое внимание уделяется деталям: популяция базы, использование транзакционности, тесты сервисов и REST - контроллеров, насторойка EntityManagerFactory, - выбор реализации пула коннектов. Особое внимание уделяется работе с базой: через Spring JDBC, Spring ORM и - Spring Data Jpa. -- Используются самые востребованные на сегодняшний момент фреймворки: Maven, Spring Security 4 - вместе с Spring Security Test, наиболее удобный для работы с базой проект Spring Data Jpa, библиотека логирования logback, реализующая SLF4J, повсеместно используемый Bootstrap и jQuery. +- Разбираются архитектурные паттерны: слои приложения и как правильно разбивать логику по слоям, когда нужно применять Data Transfer Object. То есть на выходе получается не учебный проект, а хорошо масштабируемый шаблон для большого проекта на всех пройденных технологиях. +- Большое внимание уделяется деталям: популяция базы, использование транзакционности, тесты сервисов и REST контроллеров, настройка EntityManagerFactory, выбор реализации пула коннектов. Особое внимание уделяется работе с базой: через Spring JDBC, Spring ORM и Spring Data Jpa. +- Используются самые востребованные на сегодняшний момент фреймворки: Maven, Spring Security 4 вместе с Spring Security Test, наиболее удобный для работы с базой проекта Spring Data Jpa, библиотека логирования logback, реализующая SLF4J, повсеместно используемый Bootstrap и jQuery. #### Демо разрабатываемого приложения ## План проекта (ссылки на некоторые темы открыты для просмотра) ### Архитектура проекта. Персистентность. -- Системы управления версиями -- Java 8: Lambda, Stream API -- Обзор используемых в проекте технологий и инструментов. -- Инструмент сборки Maven. -- WAR. Веб-контейнер Tomcat. Сервлеты. -- Логирование. -- Обзор стандартных библиотек. Apache Commons, Guava -- Слои приложения. Создание каркаса приложения. -- Обзор Spring Framework. Spring Context. -- Тестирование через JUnit. -- Spring Test -- Базы данных. PostgreSQL. Обзор NoSQL и Java persistence solution без ORM. -- Настройка Database в IDEA. -- Скрипты инициализации базы. Spring Jdbc Template. -- Spring: инициализация и популирование DB -- ORM. Hibernate. JPA. +- Системы управления версиями +- Java 8: Lambda, Stream API +- Обзор используемых в проекте технологий и инструментов. +- Инструмент сборки Maven. +- WAR. Веб-контейнер Tomcat. Сервлеты. +- Логирование. +- Обзор стандартных библиотек. Apache Commons, Guava +- Слои приложения. Создание каркаса приложения. +- Обзор Spring Framework. Spring Context. +- Тестирование через JUnit. +- Spring Test +- Базы данных. PostgreSQL. Обзор NoSQL и Java persistence solution без ORM. +- Настройка Database в IDEA. +- Скрипты инициализации базы. Spring Jdbc Template. +- Spring: инициализация и популирование DB +- ORM. Hibernate. JPA. - [Тестирование JPA сервиса через AssertJ](https://www.youtube.com/watch?v=BlyaXT6tOaw) -- Поддержка HSQLDB -- Транзакции -- Профили Maven и Spring -- Пул коннектов -- Spring Data JPA -- Кэш Hibernate +- Поддержка HSQLDB +- Транзакции +- Профили Maven и Spring +- Пул коннектов +- Spring Data JPA +- Кэш Hibernate ### Разработка WEB -- Spring кэш -- Spring Web -- JSP, JSTL, i18n -- Tomcat maven plugin. JNDI -- Spring Web MVC -- Spring Internationalization -- Тестирование Spring MVC -- REST контроллеры -- Тестирование REST контроллеров. Jackson. -- jackson-datatype-hibernate. Тестирование через матчеры. -- Тестирование через SoapUi. UTF-8 -- WebJars. -- Bootstrap. jQuery datatables. -- AJAX. jQuery. Notifications. -- Spring Security -- Spring Binding/Validation -- Работа с datatables через Ajax. -- Spring Security Test +- Spring кэш +- Spring Web +- JSP, JSTL, i18n +- Tomcat maven plugin. JNDI +- Spring Web MVC +- Spring Internationalization +- Тестирование Spring MVC +- REST контроллеры +- Тестирование REST контроллеров. Jackson. +- jackson-datatype-hibernate. Тестирование через матчеры. +- Тестирование через SoapUi. UTF-8 +- WebJars. +- Bootstrap. jQuery datatables. +- AJAX. jQuery. Notifications. +- Spring Security +- Spring Binding/Validation +- Работа с datatables через Ajax. +- Spring Security Test - [Кастомизация JSON (@JsonView) и валидации (groups)](https://drive.google.com/open?id=0B9Ye2auQ_NsFRTFsTjVHR2dXczA) -- Encoding password -- CSRF (добавление в проект защиты от межсайтовой подделки запроса) -- form-login. Spring Security Taglib -- Handler interceptor -- Spring Exception Handling -- Смена локали -- Фильтрация JSON через @JsonView -- Защита от XSS (Cross Site Scripting) -- Деплой в Heroku -- Локализация datatables, ошибок валидации -- Обработка ошибок 404 (NotFound) -- Доступ к AuthorizedUser -- Собеседование. Разработка ПО +- Encoding password +- CSRF (добавление в проект защиты от межсайтовой подделки запроса) +- form-login. Spring Security Taglib +- Handler interceptor +- Spring Exception Handling +- Смена локали +- Фильтрация JSON с помощью @JsonView +- Защита от XSS (Cross Site Scripting) +- Деплой в Heroku +- Локализация datatables, ошибок валидации +- Обработка ошибок 404 (NotFound) +- Доступ к AuthorizedUser +- Собеседование. Разработка ПО \ No newline at end of file diff --git a/graduation.md b/graduation.md index a4468a0f8ec9..442ce82b8c47 100644 --- a/graduation.md +++ b/graduation.md @@ -11,17 +11,17 @@ Build a voting system for deciding where to have lunch. * Users can vote on which restaurant they want to have lunch at * Only one vote counted per user * If user votes again the same day: - - If it is before 11:00 we asume that he changed his mind. + - 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 new menu each day. +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. ----------------------------- P.S.: Make sure everything works with latest version that is on github :) -P.P.S.: Asume that your API will be used by a frontend developer to build frontend on top of that. +P.P.S.: Assume that your API will be used by a frontend developer to build frontend on top of that. ----------------------------- ### ![error](https://cloud.githubusercontent.com/assets/13649199/13672935/ef09ec1e-e6e7-11e5-9f79-d1641c05cbe6.png) Рекомендации @@ -30,7 +30,7 @@ P.P.S.: Asume that your API will be used by a frontend developer to build fronte - **API продумывай с точки зрения не программиста и объектов, а с точки зрения того, кто им будет пользоваться (frontend)** - **Сначала сделай основной сценарий по ТЗ. Все остальное (если очень хочется, 3 раза подумай) - потом.** -*Представьте себе, что ПМ (лид, архитектор) дал вам ТЗ и некоторое время недоступен. У вас конечно есть много мыслей, для чего нужно приложение, как исправить ТЗ, дополнить его и сделать правильно. НО НЕ НАДО ИХ РЕАЛИЗОВЫВАТЬ В КОДЕ. Нужно сделать все максимально просто, удобно для доработок и для использования со стороны клиента (если конечно в ТЗ нет оговорок). Все свои вопросы и предложения и хотелки оформляйете отдельно (в `read.me` например). Если делаете что-то сложнее простейшего случая (например справочник еды)- обязательно напишите в read.me. Как и выбор стратегии кэширования.* +*Представьте себе, что ПМ (лид, архитектор) дал вам ТЗ и некоторое время недоступен. У вас, конечно, есть много мыслей, для чего нужно приложение, как исправить ТЗ, дополнить его и сделать правильно. НО НЕ НАДО ИХ РЕАЛИЗОВЫВАТЬ В КОДЕ. Нужно сделать все максимально просто, удобно для доработок и для использования со стороны клиента (если, конечно, в ТЗ нет оговорок). Все свои вопросы, предложения и хотелки оформляйте отдельно (в `read.me` например). Если делаете что-то сложнее простейшего случая (например, справочник еды) - обязательно напишите в read.me. Как и выбор стратегии кэширования.* > Совершенство достигнуто не тогда, когда нечего добавить, а тогда, когда нечего отнять @@ -40,20 +40,20 @@ _Антуан де Сент-Экзюпери_ - 2: **тщательно считайте количество обращений в базу на каждый запрос. Особенно при запросах от юзеров, которых очень много! Также на сложность запросов от них, чтобы не положить базу**. Самое худшее в коде - обращение в базу в цикле. - 3: **тщательно считайте количество запросов в вашем API для отображения нужной информации** - 4: учитывайте, что **пользователей может быть ОООЧЕНЬ много, а админов - МАЛО** -- 5: в проекте (и тестовом задании на работу) в отличие от нашего учебного topjava оставляйте только необходимый для работы приложения код, ничего лишнего: - - 5.1 НЕ надо делать разные профили базы и работы с ней. - - 5.2 НЕ надо делать абстрактных контроллеров на всякий случай. - - 5.3 НЕ надо делать **классов репозиториев и сервисов**, если там нет ничего, кроме делегирования. - - 5.4 Из потребностей приложения (которую надо самим придумать) реализовывать только очевидные сценарии. Те.- НИЧЕГО ЛИШНЕГО. +- 5: в проекте (и тестовом задании на работу), в отличие от нашего учебного topjava, оставляйте только необходимый для работы приложения код, ничего лишнего: + - 5.1 НЕ надо делать разные профили базы и работы с ней + - 5.2 НЕ надо делать абстрактных контроллеров на всякий случай + - 5.3 НЕ надо делать **классов репозиториев и сервисов**, если там нет ничего, кроме делегирования + - 5.4 Из потребностей приложения (которую надо самим придумать) реализовывать только очевидные сценарии. То есть НИЧЕГО ЛИШНЕГО. - 6: База Данных - берите без установки (H2 или HSQLDB). Одну!! Ваше приложение должно сразу запуститься, **без всяких настроек и переменных окружения** - - сделайте индексы к таблицам. Попробуйте обеспечит UNIQUE (один голос пользователя в день, один уникальный пункт меню в день). Следите за порядком полей в индексе. + - сделайте индексы к таблицам. Попробуйте обеспечит UNIQUE (один голос пользователя в день, один уникальный пункт меню в день). Следите за порядком полей в индексе - **историю еды и голосований сделать НУЖНО! Есть базовые вещи, которые закладываются в архитектуру приложения и неочевидные доработки к ТЗ, которых лучше не делать.** - при популировании добавте записи за сегодняшний день - now(), чтобы всегда были актуальные исходные данные - таблицы обычно именуются в единственном числе. Исключение - users, т. к. user - зарезервированное слово. `date`/`timestamp` - зарезервированное слово, лучше избегать их при именовании - 7: по возможности сделать JUnit тесты - 8: уделяйте внимание обработке ошибок -- 9: далаем REST API в соответствии с концепцией REST (url в общем имеют вид`{ресурс}/{id_ресурсa}[/{подресурс}/{id_подресурсa}][параметры]`) +- 9: делаем REST API в соответствии с концепцией REST (url в общем имеют вид`{ресурс}/{id_ресурсa}[/{подресурс}/{id_подресурсa}][параметры]`) - **[15 тривиальных фактов о правильной работе с протоколом HTTP](https://habrahabr.ru/company/yandex/blog/265569/)** - **10 Best Practices for Better RESTful API** - [REST resource hierarchy](https://stackoverflow.com/questions/20951419/what-are-best-practices-for-rest-nested-resources) @@ -62,25 +62,25 @@ _Антуан де Сент-Экзюпери_ - 12: если приложению в объекте требуется только его id, используйте reference (как мы при сохранении еды вставляем туда юзера) - 13: [Use for money in java app](http://stackoverflow.com/a/43051227/548473) - 14: еще раз про [hashCode/equals в Entity](https://stackoverflow.com/questions/5031614/the-jpa-hashcode-equals-dilemma): не делайте сравнение по полям! -- 15: название пакетов, имен классов для `model/to/web` достаточно стандартные (например `model/domain`). НЕ надо придумывать своих собственных правил. -- 16: **Используйте DATA-JPA** (сделайте без лишней делегации, напрямую из сервиса/контроллера дергать Repository). -- 17: в DATA-JPA 2.x используются `Optional`. Попробуйте работать с ними, это безопасный способ работать с null значениями (используйте `orElseThrow`). -- 18: на topjava мы смотрели разные варианты использования, тут делаем максимально просто. С TO многие вещи упрощаются. -- 19: проверьте, не торчат ли из кода учебные уши topjava, типа `ProfileRestController.testUTF()`, `AbstractServiceTest.printResult()` или закомментированные `JdbcTemplate`. Назначение этого проекта совсем другое. -- 20: ORM работает с объектами. [В простейших случаях fk_id как поля допустимы](https://stackoverflow.com/questions/6311776/hibernate-foreign-keys-instead-of-entities), но при этом JPA их уже никак не обрабатывает и не используйте их вместе с объектами. Ссылка на stackoverwrflow в коде обязательна! +- 15: название пакетов, имен классов для `model/to/web` достаточно стандартные (например `model/domain`). НЕ надо придумывать своих собственных правил +- 16: **Используйте DATA-JPA** (можно без лишней делегации, напрямую из сервиса/контроллера дергать Repository) +- 17: в DATA-JPA 2.x используются `Optional`. Попробуйте работать с ними, это безопасный способ работать с null значениями (используйте `orElseThrow`) +- 18: на topjava мы смотрели разные варианты использования, тут делаем максимально просто. С TO многие вещи упрощаются +- 19: проверьте, не торчат ли из кода учебные уши topjava, типа `ProfileRestController.testUTF()`, `AbstractServiceTest.printResult()` или закомментированные `JdbcTemplate`. Назначение этого проекта совсем другое +- 20: ORM работает с объектами. [В простейших случаях fk_id как поля допустимы](https://stackoverflow.com/questions/6311776/hibernate-foreign-keys-instead-of-entities), но при этом JPA их уже никак не обрабатывает и не используйте их вместе с объектами. Ссылка на stackoverflow в коде обязательна! - 21: проверьте, станет ли код проще с `@AuthenticationPrincipal` (урок 11, Доступ к AuthorizedUser). - 22: обновление в базе делается через `update`, даже если `delete/insert` сократит java код на несколько строк - 23: Кэширование - необязательно, но желательно - - **тщательно продумайте, что надо кэшировать (самые частые запросы)**, а что нет (большие или редкозапрашиваемые данные)! + - **тщательно продумайте, что надо кэшировать (самые частые запросы)**, а что нет (большие или редко запрашиваемые данные)! - проверьте соответствие ключей к кэшу (параметры кэшируемого метода) с конфигурацией (например в singleNonExpiryCache, heap=1 в кэше может содержаться только ОДНО значение). - 24: Валидация - желательна - одних аннотаций недостаточно. Должны быть `@Valid/@Validation` - проверяйте входные данные при `create/update` **в контроллерах!** В TopJava это `ValidationUtil.checkNew()/assureIdConsistent()` - 25: `readme.md`: - - Если задание на English, описание пишите также на English (то же самое относится к языку резюме: вакансия на English предполагает ваше резюме на English) - - Требуемые примеры `curl` не прячте- пишите здесь! + - Если задание на English, описание пишите также на English (тоже самое относится к языку резюме: вакансия на English предполагает ваше резюме на English) + - Требуемые примеры `curl` не прячьте, а пишите здесь! - Проверяют люди с опытом в Java: не надо писать инструкций, как устанавливать Java и Maven:) ## Попробуйте подергать свое API по всем типичным сценариям ТЗ! From c216f38b5127fa80985bd093b201701b0da19644 Mon Sep 17 00:00:00 2001 From: Nikilangelo Date: Thu, 12 Nov 2020 16:39:31 +0300 Subject: [PATCH 37/39] prepare to HW0 --- .../javawebinar/topjava/model/UserMeal.java | 29 ++++++++++++++ .../topjava/model/UserMealWithExcess.java | 30 ++++++++++++++ .../ru/javawebinar/topjava/util/TimeUtil.java | 9 +++++ .../topjava/util/UserMealsUtil.java | 39 +++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 src/main/java/ru/javawebinar/topjava/model/UserMeal.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/UserMealWithExcess.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/TimeUtil.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java new file mode 100644 index 000000000000..d8f91b127f6a --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java @@ -0,0 +1,29 @@ +package ru.javawebinar.topjava.model; + +import java.time.LocalDateTime; + +public class UserMeal { + private final LocalDateTime dateTime; + + private final String description; + + private final int calories; + + public UserMeal(LocalDateTime dateTime, String description, int calories) { + this.dateTime = dateTime; + this.description = description; + this.calories = calories; + } + + public LocalDateTime getDateTime() { + return dateTime; + } + + public String getDescription() { + return description; + } + + public int getCalories() { + return calories; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExcess.java b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExcess.java new file mode 100644 index 000000000000..d0aa431a35d9 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExcess.java @@ -0,0 +1,30 @@ +package ru.javawebinar.topjava.model; + +import java.time.LocalDateTime; + +public class UserMealWithExcess { + private final LocalDateTime dateTime; + + private final String description; + + private final int calories; + + private final boolean excess; + + public UserMealWithExcess(LocalDateTime dateTime, String description, int calories, boolean excess) { + this.dateTime = dateTime; + this.description = description; + this.calories = calories; + this.excess = excess; + } + + @Override + public String toString() { + return "UserMealWithExcess{" + + "dateTime=" + dateTime + + ", description='" + description + '\'' + + ", calories=" + calories + + ", excess=" + excess + + '}'; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java new file mode 100644 index 000000000000..0ebfdb5fcdcb --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java @@ -0,0 +1,9 @@ +package ru.javawebinar.topjava.util; + +import java.time.LocalTime; + +public class TimeUtil { + public static boolean isBetweenHalfOpen(LocalTime lt, LocalTime startTime, LocalTime endTime) { + return lt.compareTo(startTime) >= 0 && lt.compareTo(endTime) < 0; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java new file mode 100644 index 000000000000..3c171b4a5972 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java @@ -0,0 +1,39 @@ +package ru.javawebinar.topjava.util; + +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.model.UserMealWithExcess; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.util.Arrays; +import java.util.List; + +public class UserMealsUtil { + public static void main(String[] args) { + List meals = Arrays.asList( + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 10, 0), "Завтрак", 500), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 13, 0), "Обед", 1000), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 20, 0), "Ужин", 500), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 0, 0), "Еда на граничное значение", 100), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 10, 0), "Завтрак", 1000), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 13, 0), "Обед", 500), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 20, 0), "Ужин", 410) + ); + + List mealsTo = filteredByCycles(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); + mealsTo.forEach(System.out::println); + +// System.out.println(filteredByStreams(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000)); + } + + public static List filteredByCycles(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { + // TODO return filtered list with excess. Implement by cycles + return null; + } + + public static List filteredByStreams(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { + // TODO Implement by streams + return null; + } +} From 8fc5b7fb5837dafa1b1623948b81710daae987ca Mon Sep 17 00:00:00 2001 From: Nikilangelo Date: Mon, 16 Nov 2020 13:39:52 +0300 Subject: [PATCH 38/39] prepare to HW0 --- pom.xml | 30 +++++++++++- .../model/{UserMeal.java => Meal.java} | 14 +++++- .../{UserMealWithExcess.java => MealTo.java} | 6 +-- .../javawebinar/topjava/util/MealsUtil.java | 47 +++++++++++++++++++ .../topjava/util/UserMealsUtil.java | 39 --------------- .../javawebinar/topjava/web/UserServlet.java | 23 +++++++++ src/main/resources/logback.xml | 29 ++++++++++++ src/main/webapp/WEB-INF/web.xml | 19 ++++++++ src/main/webapp/index.html | 13 +++++ src/main/webapp/users.jsp | 11 +++++ 10 files changed, 185 insertions(+), 46 deletions(-) rename src/main/java/ru/javawebinar/topjava/model/{UserMeal.java => Meal.java} (62%) rename src/main/java/ru/javawebinar/topjava/model/{UserMealWithExcess.java => MealTo.java} (77%) create mode 100644 src/main/java/ru/javawebinar/topjava/util/MealsUtil.java delete mode 100644 src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java create mode 100644 src/main/java/ru/javawebinar/topjava/web/UserServlet.java create mode 100644 src/main/resources/logback.xml create mode 100644 src/main/webapp/WEB-INF/web.xml create mode 100644 src/main/webapp/index.html create mode 100644 src/main/webapp/users.jsp diff --git a/pom.xml b/pom.xml index 0b1c2896da5b..75660f0776f1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ ru.javawebinar topjava - jar + war 1.0-SNAPSHOT @@ -15,11 +15,15 @@ 1.8 UTF-8 UTF-8 + + + 1.2.3 + 1.7.30 topjava - install + package org.apache.maven.plugins @@ -34,6 +38,28 @@ + + + org.slf4j + slf4j-api + ${slf4j.version} + compile + + + + ch.qos.logback + logback-classic + ${logback.version} + runtime + + + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java b/src/main/java/ru/javawebinar/topjava/model/Meal.java similarity index 62% rename from src/main/java/ru/javawebinar/topjava/model/UserMeal.java rename to src/main/java/ru/javawebinar/topjava/model/Meal.java index d8f91b127f6a..943ff5cd59fa 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java +++ b/src/main/java/ru/javawebinar/topjava/model/Meal.java @@ -1,15 +1,17 @@ package ru.javawebinar.topjava.model; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; -public class UserMeal { +public class Meal { private final LocalDateTime dateTime; private final String description; private final int calories; - public UserMeal(LocalDateTime dateTime, String description, int calories) { + public Meal(LocalDateTime dateTime, String description, int calories) { this.dateTime = dateTime; this.description = description; this.calories = calories; @@ -26,4 +28,12 @@ public String getDescription() { public int getCalories() { return calories; } + + public LocalDate getDate() { + return dateTime.toLocalDate(); + } + + public LocalTime getTime() { + return dateTime.toLocalTime(); + } } diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExcess.java b/src/main/java/ru/javawebinar/topjava/model/MealTo.java similarity index 77% rename from src/main/java/ru/javawebinar/topjava/model/UserMealWithExcess.java rename to src/main/java/ru/javawebinar/topjava/model/MealTo.java index d0aa431a35d9..07f04f8dbb9f 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExcess.java +++ b/src/main/java/ru/javawebinar/topjava/model/MealTo.java @@ -2,7 +2,7 @@ import java.time.LocalDateTime; -public class UserMealWithExcess { +public class MealTo { private final LocalDateTime dateTime; private final String description; @@ -11,7 +11,7 @@ public class UserMealWithExcess { private final boolean excess; - public UserMealWithExcess(LocalDateTime dateTime, String description, int calories, boolean excess) { + public MealTo(LocalDateTime dateTime, String description, int calories, boolean excess) { this.dateTime = dateTime; this.description = description; this.calories = calories; @@ -20,7 +20,7 @@ public UserMealWithExcess(LocalDateTime dateTime, String description, int calori @Override public String toString() { - return "UserMealWithExcess{" + + return "MealTo{" + "dateTime=" + dateTime + ", description='" + description + '\'' + ", calories=" + calories + diff --git a/src/main/java/ru/javawebinar/topjava/util/MealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/MealsUtil.java new file mode 100644 index 000000000000..c29e1fbbb077 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/MealsUtil.java @@ -0,0 +1,47 @@ +package ru.javawebinar.topjava.util; + +import ru.javawebinar.topjava.model.Meal; +import ru.javawebinar.topjava.model.MealTo; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class MealsUtil { + public static void main(String[] args) { + List meals = Arrays.asList( + new Meal(LocalDateTime.of(2020, Month.JANUARY, 30, 10, 0), "Завтрак", 500), + new Meal(LocalDateTime.of(2020, Month.JANUARY, 30, 13, 0), "Обед", 1000), + new Meal(LocalDateTime.of(2020, Month.JANUARY, 30, 20, 0), "Ужин", 500), + new Meal(LocalDateTime.of(2020, Month.JANUARY, 31, 0, 0), "Еда на граничное значение", 100), + new Meal(LocalDateTime.of(2020, Month.JANUARY, 31, 10, 0), "Завтрак", 1000), + new Meal(LocalDateTime.of(2020, Month.JANUARY, 31, 13, 0), "Обед", 500), + new Meal(LocalDateTime.of(2020, Month.JANUARY, 31, 20, 0), "Ужин", 410) + ); + + List mealsTo = filteredByStreams(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); + mealsTo.forEach(System.out::println); + } + + public static List filteredByStreams(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { + Map caloriesSumByDate = meals.stream() + .collect( + Collectors.groupingBy(Meal::getDate, Collectors.summingInt(Meal::getCalories)) +// Collectors.toMap(Meal::getDate, Meal::getCalories, Integer::sum) + ); + + return meals.stream() + .filter(meal -> TimeUtil.isBetweenHalfOpen(meal.getTime(), startTime, endTime)) + .map(meal -> createTo(meal, caloriesSumByDate.get(meal.getDate()) > caloriesPerDay)) + .collect(Collectors.toList()); + } + + private static MealTo createTo(Meal meal, boolean excess) { + return new MealTo(meal.getDateTime(), meal.getDescription(), meal.getCalories(), excess); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java deleted file mode 100644 index 3c171b4a5972..000000000000 --- a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +++ /dev/null @@ -1,39 +0,0 @@ -package ru.javawebinar.topjava.util; - -import ru.javawebinar.topjava.model.UserMeal; -import ru.javawebinar.topjava.model.UserMealWithExcess; - -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.Month; -import java.util.Arrays; -import java.util.List; - -public class UserMealsUtil { - public static void main(String[] args) { - List meals = Arrays.asList( - new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 10, 0), "Завтрак", 500), - new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 13, 0), "Обед", 1000), - new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 20, 0), "Ужин", 500), - new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 0, 0), "Еда на граничное значение", 100), - new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 10, 0), "Завтрак", 1000), - new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 13, 0), "Обед", 500), - new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 20, 0), "Ужин", 410) - ); - - List mealsTo = filteredByCycles(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); - mealsTo.forEach(System.out::println); - -// System.out.println(filteredByStreams(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000)); - } - - public static List filteredByCycles(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { - // TODO return filtered list with excess. Implement by cycles - return null; - } - - public static List filteredByStreams(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { - // TODO Implement by streams - return null; - } -} diff --git a/src/main/java/ru/javawebinar/topjava/web/UserServlet.java b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java new file mode 100644 index 000000000000..ef52d67576c0 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java @@ -0,0 +1,23 @@ +package ru.javawebinar.topjava.web; + +import org.slf4j.Logger; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +import static org.slf4j.LoggerFactory.getLogger; + +public class UserServlet extends HttpServlet { + private static final Logger log = getLogger(UserServlet.class); + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + log.debug("redirect to users"); + +// request.getRequestDispatcher("/users.jsp").forward(request, response); + response.sendRedirect("users.jsp"); + } +} diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 000000000000..e9b900b26669 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,29 @@ + + + + + + + + ${TOPJAVA_ROOT}/log/topjava.log + + + UTF-8 + %date %-5level %logger{0} [%file:%line] %msg%n + + + + + + UTF-8 + %-5level %logger{0} [%file:%line] %msg%n + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000000..c63810c43593 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,19 @@ + + + Topjava + + + userServlet + ru.javawebinar.topjava.web.UserServlet + 0 + + + userServlet + /users + + + diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html new file mode 100644 index 000000000000..58d8d5ab6aec --- /dev/null +++ b/src/main/webapp/index.html @@ -0,0 +1,13 @@ + + + + Java Enterprise (Topjava) + + +

Проект Java Enterprise (Topjava)

+
+ + + diff --git a/src/main/webapp/users.jsp b/src/main/webapp/users.jsp new file mode 100644 index 000000000000..650c8dda479c --- /dev/null +++ b/src/main/webapp/users.jsp @@ -0,0 +1,11 @@ +<%@ page contentType="text/html;charset=UTF-8" %> + + + Users + + +

Home

+
+

Users

+ + \ No newline at end of file From a21aada5a952153177cb9f6968cc885753be3736 Mon Sep 17 00:00:00 2001 From: "n.pahunov" Date: Mon, 30 Aug 2021 11:57:40 +0300 Subject: [PATCH 39/39] H0 Update --- .../javawebinar/topjava/model/UserMeal.java | 29 ++++++++++++++ .../topjava/model/UserMealWithExcess.java | 30 ++++++++++++++ .../topjava/util/UserMealsUtil.java | 39 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 src/main/java/ru/javawebinar/topjava/model/UserMeal.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/UserMealWithExcess.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java new file mode 100644 index 000000000000..d8f91b127f6a --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java @@ -0,0 +1,29 @@ +package ru.javawebinar.topjava.model; + +import java.time.LocalDateTime; + +public class UserMeal { + private final LocalDateTime dateTime; + + private final String description; + + private final int calories; + + public UserMeal(LocalDateTime dateTime, String description, int calories) { + this.dateTime = dateTime; + this.description = description; + this.calories = calories; + } + + public LocalDateTime getDateTime() { + return dateTime; + } + + public String getDescription() { + return description; + } + + public int getCalories() { + return calories; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExcess.java b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExcess.java new file mode 100644 index 000000000000..d0aa431a35d9 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExcess.java @@ -0,0 +1,30 @@ +package ru.javawebinar.topjava.model; + +import java.time.LocalDateTime; + +public class UserMealWithExcess { + private final LocalDateTime dateTime; + + private final String description; + + private final int calories; + + private final boolean excess; + + public UserMealWithExcess(LocalDateTime dateTime, String description, int calories, boolean excess) { + this.dateTime = dateTime; + this.description = description; + this.calories = calories; + this.excess = excess; + } + + @Override + public String toString() { + return "UserMealWithExcess{" + + "dateTime=" + dateTime + + ", description='" + description + '\'' + + ", calories=" + calories + + ", excess=" + excess + + '}'; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java new file mode 100644 index 000000000000..3c171b4a5972 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java @@ -0,0 +1,39 @@ +package ru.javawebinar.topjava.util; + +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.model.UserMealWithExcess; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.util.Arrays; +import java.util.List; + +public class UserMealsUtil { + public static void main(String[] args) { + List meals = Arrays.asList( + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 10, 0), "Завтрак", 500), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 13, 0), "Обед", 1000), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 20, 0), "Ужин", 500), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 0, 0), "Еда на граничное значение", 100), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 10, 0), "Завтрак", 1000), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 13, 0), "Обед", 500), + new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 20, 0), "Ужин", 410) + ); + + List mealsTo = filteredByCycles(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); + mealsTo.forEach(System.out::println); + +// System.out.println(filteredByStreams(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000)); + } + + public static List filteredByCycles(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { + // TODO return filtered list with excess. Implement by cycles + return null; + } + + public static List filteredByStreams(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { + // TODO Implement by streams + return null; + } +}