From c8ee764c6babbc0ce65e3e42aee31c085534ce72 Mon Sep 17 00:00:00 2001 From: JavaOPs Date: Wed, 23 Jan 2019 17:44:44 +0300 Subject: [PATCH 01/14] Update info --- README.md | 198 ++++++++++++++++++++++++++++++++++++++++++++++++ ReleaseNotes.md | 179 +++++++++++++++++++++++++++++++++++++++++++ cv.md | 109 ++++++++++++++++++++++++++ description.md | 77 +++++++++++++++++++ graduation.md | 73 ++++++++++++++++++ 5 files changed, 636 insertions(+) create mode 100644 README.md create mode 100644 ReleaseNotes.md create mode 100644 cv.md create mode 100644 description.md create mode 100644 graduation.md diff --git a/README.md b/README.md new file mode 100644 index 000000000000..4183a09d949b --- /dev/null +++ b/README.md @@ -0,0 +1,198 @@ +Java Enterprise Online Project +=============================== +Разработка полнофункционального Spring/JPA Enterprise приложения c авторизацией и правами доступа на основе ролей с использованием наиболее популярных инструментов и технологий Java: Maven, Spring MVC, Security, JPA(Hibernate), REST(Jackson), Bootstrap (css,js), datatables, jQuery + plugins, Java 8 Stream and Time API и хранением в базах данных Postgresql и HSQLDB. + +![topjava_structure](https://user-images.githubusercontent.com/13649199/27433714-8294e6fe-575e-11e7-9c41-7f6e16c5ebe5.jpg) + + Когда вы слышите что-то, вы забываете это. + Когда вы видите что-то, вы запоминаете это. + Но только когда вы начинаете делать это, + вы начинаете понимать это + + Старинная китайская поговорка + +## Описание и план проекта +### Демо разрабатываемого приложения +### [Изменения проекта (Release Notes)](ReleaseNotes.md) +### Требования к участникам, Wiki +### Составление резюме, подготовка к интервью, поиск работы + +Вводное занятие (обязательно смотреть все видео) +=============== +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. Осваиваем Java Enterprise. Трудоустройство. Ответы на вопросы. +- Слайды презентации +- Java Tools and Technologies Landscape Report 2016 +- [Java in 2017 Survey](http://www.baeldung.com/java-in-2017) +- Из юниоров в разработчики: получаем первую работу + +#### Spring Pet-Clinic +- Spring PetClinic Sample Application +- Presentation + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2. Системы управления версиями. Git. +- **Wiki по ведению проекта в Git** +- Система управления версиями. VCS/DVSC. +- Ресурсы: + - Интерактивная Git обучалка + - Еще одна интерактивная обучалка, по-русски + - Книга Git + - Working with remote repositories + - Видео по обучению Git + - Git Overview + - [Основы Git за 20 минут](https://www.youtube.com/watch?v=TMeZGvtQnT8) + - [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\`. Иначе впоследствии будут проблемы** +> Проект постоянно улучшается, поэтому видео иногда отличается от кода проекта. Изменения указываю после видео: в `UserMeals/UserMealWithExceed` поля изменились на `private` +- **Prepare_ to_ HW0.patch (скачать и положить в каталог вашего проекта)** + +## Инструкция по шагам (из видео): +- Установить ПО (git, JDK8, IntelliJ IDEA, Maven) +- Создать аккаунт на GitHub +- Сделать Fork **ЭТОГО** проекта (https://github.com/JavaOPs/topjava) +- Сделать локальный репозиторий проекта: +
git clone https://github.com/[Ваш аккаунт]/topjava.git
+- Открыть и настроить проект в IDEA + - Выставить кодировку UTF-8 в консоли + - Поставить кодировку UTF-8 + - Поменять фонт по умолчанию (DejaVu) +- По ходу видео сделать Apply Patch... скаченного патча Prepare_ to_ HW0.patch +- Закоммитить и запушить изменения (commit + push) +- Сделать ветку домашнего задания +- Выполнить задание и залить на GitHub (commit + push) +- Переключиться в основную ветку проекта master. + +## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Домашнее задание HW0 +``` +Реализовать метод UserMealsUtil.getFilteredWithExceeded: +- должны возвращаться только записи между startTime и endTime +- поле UserMealWithExceed.exceed должно показывать, + превышает ли сумма калорий за весь день параметра метода caloriesPerDay + +Т.е UserMealWithExceed - это запись одной еды, но поле exceeded будет одинаково для всех записей за этот день. + +- Проверьте результат выполнения ДЗ (можно проверить логику в http://topjava.herokuapp.com , список еды) +- Оцените Time complexity вашего алгоритма, если он O(N*N)- попробуйте сделать O(N). +``` +- Java 8 Date and Time API +- Алгоритмы и структуры данных для начинающих: сложность алгоритмов +- Time complexity +- Временная сложность алгоритма +- Вычислительная сложность + +#### Optional (Java 8 Stream API) +``` +Сделать реализацию через Java 8 Stream API. +``` +- Видео: Доступно о Java 8 Lambda +- Java 8: Lambda выражения +- Java 8: Потоки +- Pуководство по Java 8 Stream +- [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 +- Дополнительно + - [Сергей Куксенко — Stream API, часть 1](https://www.youtube.com/watch?v=O8oN4KSZEXE) + - [Сергей Куксенко — Stream API, часть 2](https://www.youtube.com/watch?v=i0Jr2l3jrDA) + +#### Optional 2 (+5 бонусов) +``` +Сделать реализацию со сложностью O(N): +- циклом за 1 проход по List. Обратите внимание на п.13 замечаний +- через Stream API за 1 проход по исходному списку Stream meals + - возможно дополнительные проходы по частям списка + - нельзя использовать внешние коллекции, не являющиеся частью коллектора или результатами работы stream +``` +#### Замечания по использованию Stream API: +- Когда встречаешь что-то непривычное, приходится перестраивать мозги. Например, переход с процедурного на ООП программирование дается непросто. Те, кто не знает шаблонов (и не хотят учить) также их встречают плохо. Хорошая новость в том, что если это принять и начать использовать, то начинаешь получать от этого удовольствие. И тут главное не впасть в другую крайность: + - [Используйте Stream API проще (или не используйте вообще)](https://habrahabr.ru/post/337350/) +- Если вас беспокоить производительность стримов, обязательно прочитайте про оптимизацию + - ["Что? Где? Когда?"](http://optimization.guide/intro.html) + - [Перформанс: что в имени тебе моём?](https://habrahabr.ru/company/jugru/blog/338732/) + - [Performance это праздник](https://habrahabr.ru/post/326242/) + +При использовании Stream API производительность улучшиться только на больших задачах, где возможно распараллеливание. +Еще - просто так запустить и померять скорость JVM нельзя (как минимум дать прогреться и запустить очень большое число раз). Лучше использовать какие-нибудь бенчмарки, например [JMH](http://tutorials.jenkov.com/java-performance/jmh.html), который мы юзаем на другом проекте (Mastejava). + +## ![error](https://cloud.githubusercontent.com/assets/13649199/13672935/ef09ec1e-e6e7-11e5-9f79-d1641c05cbe6.png) Замечания к HW0 +- 1: Код проекта менять можно! Одна из распространенных ошибок как в тестовых заданиях на собеседовании, так и при работе на проекте, что ничего нельзя менять. Конечно при правках в рабочем проекте обязательно нужно проконсультироваться/проревьюироваться у авторов кода (находится по истории VCS) +- 2: Наследовать `UserMealWithExceed` от `UserMeal` я не буду, т.к. это разные сущности: Transfer Object и Entity. Мы будет их проходить на 2м уроке. +- 3: Правильная реализация должна быть простой и красивой, можно сделать 2-мя способами: через стримы и через циклы. Сложность должна быть O(N), т.е. без вложенных стримов и циклов. +- 4: При реализации через циклы посмотрите в `Map` на методы `getOrDefault` или `merge` +- 5: **При реализации через `Stream` заменяйте `forEach` оператором `stream.map(..)`** +- 6: Объявляйте переменные непосредственно перед использованием (если возможно - сразу с инициализацией). При объявлении коллекций используйте тип переменной - интерфейс (Map, List, ..) +- 7: Если IDEA предлагает оптимизацию (желтым подчеркивает), например заменить лямбду на метод-референс, соглашайтесь (Alt+Enter) +- 8: Пользуйтесь форматированием кода в IDEA: `Alt+Ctrl+L` +- 9: Перед check-in проверяйте чендж-лист (курсор на файл и Ctrl+D): не оставляйте в коде ничего лишнего (закомментированный код, TODO и пр.). Если файл не меняется (например только пробелы или переводы строк), не надо его чекинить, делайте ему `revert` (Git -> Revert / `Ctrl+Alt+Z`). +- 10: `System.out.println` нельзя делать нигде, кроме как в `main`. Позже введем логирование. +- 11: Результаты, возвращаемые `UserMealsUtil.getFilteredWithExceeded` мы будем использовать [в нашем приложении](http://topjava.herokuapp.com/) для фильтрации по времени и отображения еды правильным цветом. +- 12: Обращайте внимание на комментарии к вашим коммитам в git. Они должны быть короткие и информативные (лучше на english) +- 13: Не полагайтесь в решении на то, что список будет подаваться отсортированным. Такого условия нет. +----- + +### Полезные ресурсы +> ВНИМАНИЕ: +> - ДЗ первого урока будет связано с созданием небольшого CRUD приложения (в памяти, без DB) на JSP и сервлетах. Введение будет, но предварительное знакомство не помешает. +> - основы JavaSсript необходимы для понимания проекта, начиная с 8-го занятия! + +Все остальное - опционально. + +#### HTML, JavaScript, CSS +- [Basic HTML and HTML5](https://learn.freecodecamp.org/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements/) +- [Справочник по WEB](https://developer.mozilla.org/ru/) +- [Видео по WEB технологиям](https://www.youtube.com/user/WebMagistersRu/playlists) +- [Изучение JavaScript в одном видео уроке за час](https://www.youtube.com/watch?v=QBWWplFkdzw) +- HTML, CSS, JAVASCRIPT, SQL, JQUERY, BOOTSTRAP +- Введение в программирование на JavaScript +- Стандарты кодирования для HTML, CSS и JavaScript’a +- Основы работы с HTML/CSS/JavaScript +- JavaScript - Основы +- Основы JavaScript +- Bootstrap 3 - Основы +- jQuery для начинающих + +#### Java (базовые вещи) +- Интуит. Программирование на Java +- 1й урок MasterJava: Многопоточность +- Основы Java garbage collection +- Размер Java объектов +- Введение в Java Reflection API +- Структуры данных в картинках +- Обзор java.util.concurrent.* +- Синхронизация потоков +- String literal pool +- Маленькие хитрости Java +- A Guide to Java 8 + +### Туториалы, разное +[Что нужно знать о бэкенде новичку в веб-разработке](https://tproger.ru/translations/backend-web-development) +[Туториалы: Spring Framework, Hibernate, Java Core, JDBC](http://proselyte.net/tutorials/) + +#### Сервлеты +- Как создать Servlet? Полное руководство. + +#### 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/ReleaseNotes.md b/ReleaseNotes.md new file mode 100644 index 000000000000..5298ae94db76 --- /dev/null +++ b/ReleaseNotes.md @@ -0,0 +1,179 @@ +# TopJava Release Notes +### Topjava 15 +- Миграция на Servlet API 4.0 / Tomcat 9.x +- [Миграция на JDK11](http://javaops.ru/view/resources/jdk8_11) +- JUnit5 fix: junit-platform-surefire-provider не нужен +- Рефакторинг тестов: + - в `RootControllerTest.testUsers` для проверки используем `AssertionMatcher` адаптер + - вместо `content().json()` от `jsonassert` десериализуем json и используем сравнения через `AssertJ` +- В javascript место глабальных переменных и одинаковой функции обновления таблицы задаю их в объекте контекст, который передаю в `makeEditable()` как параметр +- Починил `back` в браузере после логина. Кнопки входа и регистрации отображаю только для `isAnonymous()` + +### Topjava 14 +- [Миграция на JUnit 5](http://javaops.ru/view/resources/junit5) +- Для измерения времени в тестах использую [Spring StopWatch](https://www.logicbig.com/how-to/code-snippets/jcode-spring-framework-stopwatch.html) +- `SimpleJdbcInsert` и `NamedParameterJdbcTemplate` конструируются (и берут настройки) из `jdbcTemplate` +- `AuthorizedUser` зарефакторился в `SecurityUtil` +- В javascript [заменил `var` на `let/const`](https://learn.javascript.ru/let-const). [Поддержка 95% браузеров](https://caniuse.com/#feat=const) +- Подправил UI фильтрации и заголовка страниц, добавилась кнопка `Cancel` в профиль +- Починил [баг в FireFox](https://bugzilla.mozilla.org/show_bug.cgi?id=884693): пустой ответ по ajax +- Сделал вход в приложение при нажании кнопок `Зайти как ...` +- Добавил регистрацию пользователя по REST +- Преименовал js файлы согласно [javascript filename naming convention](https://stackoverflow.com/questions/7273316/what-is-the-javascript-filename-naming-convention) +- Сделал проверку startTime/endTime на фильтре времени (после обновления datetimepicker до 2.5.20) + +### Topjava 13 +- [Миграция на Botstrap 4](https://getbootstrap.com/docs/4.1/migration/) +- Добавил [Responsive behaviors](https://getbootstrap.com/docs/4.1/components/navbar/#responsive-behaviors) - при уменшении ширины экрана навигация сворачивается в кнопку +- Для отображения цвета еды и выключенного юзера использую [data-* атрибуты](https://developer.mozilla.org/ru/docs/Web/Guide/HTML/Using_data_attributes) +- В `inputField.tag` передаю как параметр код для локализации label, а в `i18n.jsp` передаю как параметр `page`. См. [JSP include action with parameter example](https://beginnersbook.com/2013/12/jsp-include-with-parameter-example) + +### Topjava 12 +- [Миграция на Spring 5](http://javaops.ru/view/resources/spring5) +- обновил версии: Ehcache 3.x, datatables, datetimepicker +- добавил видео решений HW0 с одним проходом +- поправил видео [Обзор Spring Framework. Spring Context](https://drive.google.com/file/d/1fBSLGEbc7YXBbmr_EwEHltCWNW_pUmIH). Дописал про Constructor injection. +- заменил видео про тетсирование сервисов. Вместо самодельных матчеров стали использовать [AssertJ](http://joel-costigliola.github.io/assertj/index.html). Видео [Тестирование UserService через AssertJ](https://drive.google.com/open?id=1SPMkWMYPvpk9i0TA7ioa-9Sn1EGBtClD), время 1:53 +- сделал [видео с jQuery конвертерами и дефолтными группами валидации при сохранении в базу](https://drive.google.com/open?id=1tOMOdmaP5OQ7iynwC77bdXSs-13Ommax) +- сделал [видео с новым `DelegatingPasswordEncoder` и Json READ/WRITE access](https://drive.google.com/file/d/1XZXvOThinzPw4EhigAUdo8-MWT_g8wOt/view?usp=sharing) +- убрал `AccessType.PROPERTY` для `AbstractBaseEntity.id` (см. [fixed HHH-3718](https://hibernate.atlassian.net/browse/HHH-3718)) +- удалил `PasswordUtil`, возвращаю статус `NO_CONTENT` для REST delete, убрал группы валидации в `UserTo` +- заменил в jQuery [success на done](https://stackoverflow.com/a/22213543/548473) +- вместо `lang.jsp` сделал общий `bodyHeader.jsp` + +### Topjava 11 +- добавил + - доп. решение HW1 через одним return и O(N) + - раскрасил лог ([Logback layouts coloring](https://logback.qos.ch/manual/layouts.html#coloring)) +- рефакторинг + - починил коммит формы по cancel (`history.back()`) в FireFox + - заменил неработающий DependencyCi на [VersionEye](https://www.versioneye.com/) c проверкой зависимостей на uptodate + - починил `CrudUserRepository.getWithMeals()` через `@EntityGraph`. С неколькими ролями (у админа) еда дублируется + - починил тесты контроллеров с профилем JDBC (`JpaUtil` отсутствует в контексте JDBC) + - переименовал `meal.jsp/user.jsp` в `mealForm.jsp/userForm.jsp` + - в `InMemoryMealRepositoryImpl.save()` сделал update атомарным + - переименовал методы сервисов `save` в `create` + - переименовал и cделал классы `BaseEntity` и `NamedEntity` абстрактными + - обновил Noty и API с ним до 3.1.0. Добавил glyphicon в сообщения Noty + - заменил `MATCHER_WITH_EXCEED` на валидацию через [JSONassert](https://github.com/skyscreamer/JSONassert). + - поменял Deprecated валидаторы `org.hibernate.validator.constraints` на `javax.validation.constraints` + - убрал пароль из результатов REST через [@JsonProperty READ_ONLY / WRITE_ONLY](https://stackoverflow.com/questions/12505141/only-using-jsonignore-during-serialization-but-not-deserialization/12505165#12505165). Тесты на REST пришлось починить добавлением добавлением в JSON пароля как дополнительного параметра (`JsonUtil.writeWithExtraProps`) + - **убрал JSON View и сделал преобразование времени на UI с помощью [jQuery converters](http://api.jquery.com/jQuery.ajax/#using-converters)** + - **поменял [группу валидации по умолчанию при сохранении через JPA](https://stackoverflow.com/questions/16930623/16930663#16930663).** Теперь + все валидаторы в модели работаю по умолчанию (`groups` не требуется). + - Добавил в `ErrorInfo` тип ошибки `ErrorType` + i18n. + +- правки + - переименовал `ModelMatcher` в `BeanMatcher` и починил: можно сравнивать только упорядоченные коллекции (List) + - поменял зависимость `org.hibernate:hibernate-validator` на `org.hibernate.validator:hibernate-validator` (warning при сборке) + +### Topjava 10 +- добавил + - доступ к AuthorizedUser через [`@AuthenticationPrincipal`](http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#mvc-authentication-principal) и [authentication Tag](http://docs.spring.io/spring-security/site/docs/current/reference/html/taglibs.html#the-authentication-tag) + - [Обработку 404 NotFound](https://stackoverflow.com/questions/18322279/spring-mvc-spring-security-and-error-handling) + - локализацию ошибок валидации + - проверки json в тестах через [JSONassert](https://github.com/skyscreamer/JSONassert) и [через jsonPath](https://www.petrikainulainen.net/programming/spring-framework/integration-testing-of-spring-mvc-applications-write-clean-assertions-with-jsonpath/) + - [логирование от Postgres Driver](http://stackoverflow.com/a/43242620/548473) + - в `.travis.yml` [сборку только ветки master](https://docs.travis-ci.com/user/customizing-the-build#Building-Specific-Branches) + - [защиту от кэширование ajax запросов в IE](https://stackoverflow.com/a/4303862/548473) + - обработку запрета модификации системный юзеров через универсальный `ApplicationException` + - рефакторинг + - сделал `@EntityGraph` через `attributePaths` + - реализаовал обработку дублирования `user.email` и `meal.dateTime` через [Controller Based Exception Handling](https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc#controller-based-exception-handling) + - поменял отключение транзакционности в тестах через `@Transactional(propagation = Propagation.NEVER)` + - сделал выбор в сервлете через switch + - [все логгирование сделал через {} форматирование](http://stackoverflow.com/questions/10555409/logger-slf4j-advantages-of-formatting-with-instead-of-string-concatenation) и поправил его в контроллерах (поле проверки id) + - [перешел на конструктор DI](http://stackoverflow.com/questions/39890849/what-exactly-is-field-injection-and-how-to-avoid-it) + - в `ModelMatcher` переименовал `Comparator` -> `Equality` + - [заинлайнил все лямбды](http://stackoverflow.com/questions/19718353/is-repeatedly-instantiating-an-anonymous-class-wasteful) (компараторы, ModelMatcher.equality) + - поменялась реализация `JdbcUserRepositoryImpl.getAll()` + - на UI кнопки в таблице заменились на линки, поправил сообщения локализации + - [сделал кастомизацию JSON (@JsonView) и валидацию (groups)](https://drive.google.com/file/d/0B9Ye2auQ_NsFRTFsTjVHR2dXczA) для данных еды, отдаваемых на UI + - в `JdbcUserRepositoryImpl` поменял `MapSqlParameterSource` на `BeanPropertySqlParameterSource` +- удалил + - зависимость `javax.transaction.jta` (уже не нужна) + - `${spring.version}` в `pom.xml` зависимостях (уже есть в `spring-framework-bom`) + - distinct из запроса Hibernate на пользователей с ролями. [Оптимизация запроса distinct: 15.16.2](https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#hql-distinct) + - лишние `
` тэги (`shadow` и `view-box`) + +### Topjava 9 +- добавил + - выбор профиля базы через `ActiveProfilesResolver`/`AllActiveProfileResolver` на основе драйвера базы в classpath + - видео Cascade. Auto generate DDL. + - проверку на правильность id в Ajax/Rest контроллерах (treat IDs in REST body) + - тесты на валидацию входных значений контроллеров и зависимость на имплементацию + - Bootstrap Glyphicons +- рефакторинг + - переименовал `TimeUtil` в `DateTimeUtil` + - переименовал `ExceptionUtil` в `ValidationUtil` + - заменил валидацию `@NotEmpty` на `@NotBlank` + - заменил `CascadeType.REMOVE` на `@OnDelete` + - изменил `JdbcUserRepositoryImpl.getAll()` + - обновил jQuery до 3.x, исключил из зависимостей webjars ненужные jQuery + - cделал загрузку скриптов асинхронной + - фильтр еды сделал в [Bootstrap Panels](http://getbootstrap.com/components/#panels) + - вместо `Persistable` ввел интерфейс `HasId` и наследую от него как Entity, так и TO + - сделал универсальную обработку исключений дублирования email и dateTime + +### Topjava 8 +- добавил: + - [защиту от XSS (Cross-Site Scripting)](http://stackoverflow.com/a/40644276/548473) + - интеграцию с Dependency Ci и Travis Ci + - локализацию календаря + - сводку по результатам тестов + - примеры запросов curl в `config/curl.md` + - DataTables/Bootstrap 3 integration + - тесты на профиль деплоя Heroku (общее количество JUnit тестов стало 102) +- удалил зависимость `jul-to-slf4j` +- рефакторинг + - переименовал все классы `UserMeal**` в `Meal**`, JSP + - переименовал `LoggedUser` в `AuthorizedUser` + - починил работа с PK Hibernate в случае ленивой загрузки (баг HHH-3718) + - поменял в `BaseEntity` `equals/hashCode/implements Persistable` + - в `InMemoryMealRepositoryImpl` выделил метод `getAllStream` + - перенес проверки пердусловий `Assert` из `InMemory` репозиториев в сервисы + - переименовал классы _Proxy*_ на более адекватные _Crud*_ + - поменял реализацию `JpaMealRepositoryImpl.get`, добавил в JPA модель `@BatchSize` + - вместо `@RequestMapping` ввел Spring 4.3 аннотации `@Get/Post/...Mapping` + - поменял авторизацию в тестах не-REST контроллеров + - перенес вызовы `UserUtil.prepareToSave` из `AbstractUserController` в `UserServiceImpl` + - зарефакторил обработку ошибок (`ExceptionInfoHandler`) + +### Topjava 7 +- добавил: + - [JPA 2.1 EntityGraph](https://docs.oracle.com/javaee/7/tutorial/persistence-entitygraphs002.htm) + - [Jackson @JsonView](https://habrahabr.ru/post/307392/) + - валидацию объектов REST + - [i18n в JavaScript](http://stackoverflow.com/a/6242840/548473) + - проверку предусловий и видео Методы улучшения качества кода + - интеграцию с проверкой кода в Codacy + - [сравнение вермени исполнения запросов при различных meals индексах](https://drive.google.com/open?id=0B9Ye2auQ_NsFX3RLcnJCWmQ2Y0U) +- tomcat7-maven-plugin плагин перключили на Tomcat 8 (cargo-maven2-plugin) +- рефакторинг + - обработка ошибок сделал с array + - матчеров тестирования (сделал автоматические обертки и сравнение на основе передаваемого компаратора) + - вынес форматирование даты в `functions.tld` + +### Topjava 3-6 +- добавил + - [выпускной проект](https://drive.google.com/open?id=0B9Ye2auQ_NsFcG83dEVDVTVMamc) + - в таблицу meals составной индекс + - константы `Profiles.ACTIVE_DB`, `Profiles.DB_IMPLEMENTATION` + - проверки и тесты на `NotFound` для `UserMealService.getWithUser` и `UserService.getWithMeals` + - в MockMvc фильтр CharacterEncodingFilter + - защиту от межсайтовой подделки запроса, видео Межсайтовая подделка запроса (CSRF) + - ограничение на диапазон дат для фильтра еды +- рефакторинг + - UserMealsUtil, ProfileRestController, компараторов в репозитоии + - `LoggedUser` отнаследовал от `org.springframework.security.core.userdetails.User` + - переименовал `DbTest` в `AbstractServiceTest` и перенес сюда `@ActiveProfiles` + - сделал выполнение скриптов в тестах через аннотацию `@Sql` + - вместо использования id и селектора сделал обработчик `onclick` + - изменил формат ввода даты в форме без 'T' +- убрал + - `LoggerWrapper` + - Dandelion обертку к datatables +- обновил + - Hibernate до 5.x и Hibernate Validator, добавились новые зависимости и `jackson-datatype-hibernate5` + - datatables API (1.10) + - Postgres драйвер. Новый драйвер поддерживает Java 8 Time API, разделил реализацию JdbcMealRepositoryImpl на Java8 (Postgresql) и Timestamp (HSQL) diff --git a/cv.md b/cv.md new file mode 100644 index 000000000000..2571ae7a0605 --- /dev/null +++ b/cv.md @@ -0,0 +1,109 @@ +## Составление резюме, подготовка к интервью, поиск работы + +![cv](https://cloud.githubusercontent.com/assets/13649199/10877471/93ea86b8-8157-11e5-9bfa-95e3fba75c58.jpg) + +- Научиться программировать сложнее, чем кажется +- [Собеседование. Разработка ПО. Вопросы.](https://drive.google.com/open?id=0B9Ye2auQ_NsFQVc2WUdCR0xvLWM) +- [Набор ссылок для тренировки и прохождения интервью](https://github.com/andreis/interview) + +### Составление резюме: +- [VisualCV: create resume in minutes](https://www.visualcv.com/) +- Выбрать шаблон для резюме +- [GitHub Pages](https://pages.github.com/), Resume template +- Как продать свое резюме в 2 раза дороже +- Как правильно составить резюме +- Резюме программистов. Часть 1 (плохие) +- Резюме программистов. Часть 2 (хорошие) +- Как составить резюме на английском +- ОФОРМЛЕНИЕ IT-РЕЗЮМЕ для USA + +### Наши истории (делимся опытом и успехом) + +### Тесты/задачи онлайн: +- [Java Programming Test](https://tests4geeks.com/java) +- game: test Java skills +- Codility lesson tests +- Quizful- тесты онлайн +- LeetCode Online Judge +- Sphere online judge +- Codility programmers lessons +- Hackerrank practice coding + +## [Тестовое собеседование, самые спрашиваемые темы](http://javaops.ru/interview/test.html) + +### Интервью: +- Михаил Портнов. Собеседование на работу: как продать себя грамотно +- Михаил Портнов. Какие вопросы мы задаем на собеседовании? +- Михаил Портнов. Собеседование на работу: жизненный путь +- Канал: Резюме, поиск работы, интервью +- Яков Файн: Как стать профессиональным Java разработчиком +- Ответы на вопросы на собеседовании Junior Java Developer +- Список вопросов с ответами для собеседования по Java +- Сборка по вопросам на интервью +- Сборка вопросов-ответов от JavaStudy +- [Вопросы по классам коллекциям от JavaRush-1](http://info.javarush.ru/translation/2013/10/08/Часто-задаваемые-на-собеседованиях-вопросы-по-классам-коллекциям-в-Java-Часть-1-.html) +- [Вопросы по классам коллекциям от JavaRush-2](http://info.javarush.ru/translation/2013/10/08/Часто-задаваемые-на-собеседованиях-вопросы-по-классам-коллекциям-в-Java-Часть-2-.html) +- Тест на знание SQL +- Вопросы на собеседовании Java Junior Developer +- Java вопросы с собеседований на Android +- Сборка вопросов от JavaRush +> про clone и finalize объязательно прочтите Джошуа Блох: Java. Эффективное программирование (второе издание) + +- Cracking the Coding Interview +> Особенно обратите внимание на раздел: Часть VIII. Вопросы собеседования + + +### От себя: +- email, skype - очень желательно, чтобы по ним вы были узнаваемы. Заведите рабочие, если не так. +- написать ВЕСЬ IT опыт (исключая опыт пользователя: Windows, MS Word, Photophop, Yandex disk, Google docs, ..): технологии, какие задачи решали (конкретные), какие инструменты использовали, VCS, DB, инструменты сборки, ... включая опыт в ВУЗе. +- на English иметь желательно. Если вакансия опублинована на Englsih - шлите на нем. Часто могут на нем попросить, если работодатель иностранный. +- удобно иметь резюме где то в инете (hh, linkedin, google doc, чтобы им было удобно делиться). + +### Позиционирование проекта Topjava: +- Обязательно убери из резюме **любое упоминание Junior**. Количество обращений возрастет на порядок. Ссылку на стажировку можно поставить: http://javaops.ru/view/topjava (в linkedin: https://www.linkedin.com/company/java-online-projects). +- После завершения проекта ты освошь все заявленные в нем технологии - вставь их в квалификацию (включая java 8 Stream and Time API). +- В разделе опыт работы (если нет коммерческого опыта) вставь: + + Участие в разработке Spring/JPA Enterprise приложения c авторизацией и правами доступа на основе ролей + на стеке Maven/ Spring MVC/ Security/ REST(Jackson)/ Java 8 Stream API: + - реализация сохранения в базы Postgres и HSQLDB на основе Spring JBDC, JPA(Hibernate) и Spring-Data-JPA + - реализация и тестирование REST и AJAX контроллеров + - реализация клиента на Bootstrap (css/js), datatables, jQuery + plugins. + - собственная доработка проекта + +- Делай упор не на обучение, а на **участие в проекте**. Выполнение домашних заданий это полноценное участие с написанием функционала по всем пройденным технологиям. На собеседовании смотрят не на то, что ты заканчивал, а на опыт и знания. + +### В процессе обучения +- Если рассмотриваешь предложения по работе, подними в своем профиле этот флаг и обязательно заполни ссылку на резюме. Обновления нашей базы выпускников смотрят уже более 125 партнеров по трудоустройству (компании и индивидуальные рекрутеры). Проверь содержание "Информация для HR": по нему принимают решение, открывать резюме или нет. + +- Вступайте в нашу группу участников Slack: каналы помощи с Java, отзывы о работодателях, обсуждение тестовых заданий, вакансии, цены на рынке труда, IT события, интересные видео и многое другое. + +- Подпишитесь на рассылку вакансий под себя + +### После прохождения испытательного срока жду твою [историю успеха](http://javaops.ru/view/story) + +### Основные сайты поиска работы: +- Яндекс агрегатор +- HH +- LinkedIn +- djinni.co (более актуально для Украины) + +## Как выжить на испытательном сроке +- Учись грамотно формулировать проблему. Проблема "у меня не работает" может иметь тысячи причин. В + процессе формулирования очень часто приходит ее решение. +- Учись инвестигировать проблему. Внимательное чтение логов и умение дебажить - основные навыки + разработчика. В логах надо читать верх самого нижнего эксепшена - там причина всей портянки. +- Грамотно уделяй время каждой проблеме. Две крайности - сразу бросаться за помощью и + бится нам ней часами. + Пробуй решить ее сам и в зависимости от проблемы выделяй на это разумное время. +- Если тебе что-то объясняют по проекту - обязательно записывай. +- Когда получаешь задачу - уточни все очень подробно. +- Получай в процессе решения обратную связь - в том ли направлении ты идешь. +- Не игнорируй совместные ланчи (курилки) +- Готовься к стендапам/летучкам. Задавай на них вменяемые вопросы. Выказывай заинтересованность +- Выдели самое главное путем опроса босса и важных коллег. Не распыляйся на мелочи. +- [**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) +- [Нетехнические навыки](https://tproger.ru/experts/softskills-for-job) + +## [Отзывы по стажировке Topjava](https://vk.com/topic-74381644_30447246) diff --git a/description.md b/description.md new file mode 100644 index 000000000000..d2448ca99e57 --- /dev/null +++ b/description.md @@ -0,0 +1,77 @@ +#### Разработка полнофункционального 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 для работы с ленивой загрузкой +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. + +#### Демо разрабатываемого приложения + +## План проекта (ссылки на некоторые темы открыты для просмотра) +### Архитектура проекта. Персистентность. +- Системы управления версиями +- 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 + +### Разработка 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 +- [Кастомизация 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 +- Собеседование. Разработка ПО diff --git a/graduation.md b/graduation.md new file mode 100644 index 000000000000..f167155ab997 --- /dev/null +++ b/graduation.md @@ -0,0 +1,73 @@ +## Выпускной проект +Design and implement a REST API using Hibernate/Spring/SpringMVC (or Spring-Boot) **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 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 after 11:00 then it is too late, vote can't be changed + +Each restaurant provides 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. + +----------------------------- +### ![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, излишние делегирования и наследования - **не нужны!** +- **API продумывай с точки зрения не программиста и объектов, а с точки зрения того, кто им будет пользоваться (frontend)** +- **Сначала сделай основной сценарий по ТЗ. Все остальное (если очень хочется, 3 раза подумай) - потом.** + +*Представьте себе, что ПМ (лид, архитектор) дал вам ТЗ и некоторое время недоступен. У вас конечно есть много мыслей, для чего нужно приложение, как исправить ТЗ, дополнить его и сделать правильно. НО НЕ НАДО ИХ РЕАЛИЗОВЫВАТЬ В КОДЕ. Нужно сделать все максимально просто, удобно для доработок и для использования со стороны клиента (если конечно в ТЗ нет оговорок). Все свои вопросы и предложения и хотелки оформляйете отдельно (в `read.me` например). Если делаете что-то сложнее простейшего случая (например справочник еды)- объязательно напишите в read.me. Как и выбор стратегии кэширования.* + +> Совершенство достигнуто не тогда, когда нечего добавить, а тогда, когда нечего отнять + +_Антуан де Сент-Экзюпери_ + +- 1: **читаем ТЗ ОЧЕНЬ внимательно, НЕ надо ничего своего туда домысливать и творчески изменять** +- 2: **тщательно считайте количество обращений в базу на каждый запрос. Особенно при запросах от юзеров, которых очень много! Также на сложность запросов от них, чтобы не положить базу** +- 3: **тщательно считайте количество запросов в вашем API для отображения нужной информации** +- 4: **учитывайте, что пользователей может быть ооочень много, а админов- мало** +- 5: в проекте (и тестовом задании на работу) в отличие от нашего учебного topjava оставляйте только необходимый для работы приложения код, ничего лишнего: + - 5.1 НЕ надо делать разные профили базы и работы с ней. + - 5.2 НЕ надо делать абстрактных контроллеров на всякий случай. + - 5.3 НЕ надо делать **классов репозиториев и сервисов**, если там нет ничего, кроме делегирования. + - 5.4 Из потребностей приложения (которую надо самим придумать) реализовывать только очевидные сценарии. Те.- НИЧЕГО ЛИШНЕГО. +- 6: базу лучше взять без установки (H2 или HSQLDB). Ваше приложение должно сразу запуститься **ОПТИМАЛЬНО- без всяких настроек** +- 7: по возможности сделать JUnit тесты +- 8: уделяйте внимание обработке ошибок +- 9: далаем REST API в соответствии с концепцией REST, **с учетом иерархии принадлежности объектов** + - [15 тривиальных фактов о правильной работе с протоколом HTTP](https://habrahabr.ru/company/yandex/blog/265569/) + - 10 Best Practices for Better RESTful API +- 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`). НЕ надо придумывать своих собственных правил. +- 16: **Используйте DATA-JPA** (можно без лишней делегации, напрямую из сервиса/контроллера дергать Repository). +- 17: В DATA-JPA 2.x используются `Optional`. Попробуйте работать с ними, это безопасный способ работать с null значениями. +- 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: Если используете кэширование, **тщательно продумайте, что надо кэшировать (самые частые запросы)**, а что нет (большие или редкозапрашиваемые данные)! + +## Попробуйте подергать свое API по всем типичным сценариям ТЗ! +- Удобно использовать? Можно сделать проще? Например чтобы проголосовать за ресторан залогиненному юзеру достаточно `restorauntId`. +- Удовлетворяет ли принципам REST (см. ссылки выше)? +- Сколько раз пришлось его вызвать API для типичного сценария (нарпимер посмотреть рестораны с едой)? +- Сколько запросов к базе было сделано? Можно ли сократить (например с FETCH/Graph или через кэширование)? From 77f5d45abb946d71ae30f760907d346f5c7aa027 Mon Sep 17 00:00:00 2001 From: JavaOPs Date: Thu, 28 Mar 2019 17:23:13 +0300 Subject: [PATCH 02/14] Add sample lesson07 Update read.me --- README.md | 9 ++- doc/lesson07.md | 174 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 doc/lesson07.md diff --git a/README.md b/README.md index 4183a09d949b..d6e1d486e3b9 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Java Enterprise Online Project ## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Домашнее задание HW0 ``` -Реализовать метод UserMealsUtil.getFilteredWithExceeded: +Реализовать метод UserMealsUtil.getFilteredWithExceeded через циклы (`forEach`): - должны возвращаться только записи между startTime и endTime - поле UserMealWithExceed.exceed должно показывать, превышает ли сумма калорий за весь день параметра метода caloriesPerDay @@ -73,7 +73,7 @@ Java Enterprise Online Project Т.е UserMealWithExceed - это запись одной еды, но поле exceeded будет одинаково для всех записей за этот день. - Проверьте результат выполнения ДЗ (можно проверить логику в http://topjava.herokuapp.com , список еды) -- Оцените Time complexity вашего алгоритма, если он O(N*N)- попробуйте сделать O(N). +- Оцените Time complexity алгоритма. Если она больше O(N), например O(N*N) или N*log(N), сделайте O(N). ``` - Java 8 Date and Time API - Алгоритмы и структуры данных для начинающих: сложность алгоритмов @@ -81,6 +81,8 @@ Java Enterprise Online Project - Временная сложность алгоритма - Вычислительная сложность +#### ВНИМАНИЕ: варианты Optional делайте в `UserMealsUtil` в одной ветке в разных методах. Проще делать, проще проверять + #### Optional (Java 8 Stream API) ``` Сделать реализацию через Java 8 Stream API. @@ -88,7 +90,8 @@ Java Enterprise Online Project - Видео: Доступно о Java 8 Lambda - Java 8: Lambda выражения - Java 8: Потоки -- Pуководство по Java 8 Stream +- Pуководство по Java 8 Stream +- Java 8 Stream API в картинках и примерах - [7 способов использовать groupingBy в Stream API](https://habrahabr.ru/post/348536) - Лямбда-выражения в Java 8 - A Guide to Java 8 diff --git a/doc/lesson07.md b/doc/lesson07.md new file mode 100644 index 000000000000..7326f915dc06 --- /dev/null +++ b/doc/lesson07.md @@ -0,0 +1,174 @@ +# [Онлайн стажировка Spring 5/JPA Enterprise (Topjava)](http://javaops.ru/view/topjava) + +## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Разбор домашнего задания HW6 + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. HW6 +#### Apply 7_01_HW6_fix_tests.patch +> - Добавил `AbstractServiceTest.isJpaBased()` и `Assume.assumeTrue(isJpaBased())` в `AbstractMealServiceTest.testValidation()`. +> - Как вариант можно было вместо наследования от `AbstractJpaUserServiceTest` сделать `@Autowired(required = false) JpaUtil` (в этом случае, если в профиле jpa/datajpa не объявить `JpaUtil`, в тестах будет NPE) +> - В новой версии Spring классы `spring-mvc` требуют `WebApplicationContext`, поэтому поправил `inmemory.xml` + + +#### Apply 7_02_HW6_meals.patch +При переходе на AJAX `JspMealController` удалим за ненадобностью, возвращение всей еды `meals()` останется в `RootController`. + +#### Apply 7_03_HW6_fix_relative_url_utf8.patch +- Relative paths in JSP +- Spring redirect: prefix + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2. HW6 Optional +#### Apply 7_04_HW6_optional_add_role.patch +`JdbcUserServiceTest` отвалились. Будем чинить в `7_06_HW6_optional_jdbc.patch` + +#### Apply 7_05_fix_hint_graph.patch +- В `JpaUserRepositoryImpl.getByEmail` DISTINCT попадает в запрос, хотя он там не нужен. Это просто указание Hibernate не дублировать данные. +Для оптимизации можно указать Hibernate делать запрос без distinct: [15.16.2. Using DISTINCT with entity queries](https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#hql-distinct) +- Тест `DataJpaUserServiceTest.testGetWithMeals()` не работает для admin (у админа 2 роли и еда при JOIN дублируется). `DISTINCT` при несколький JOIN не помогает. +Оставил в графе только `meals`. Корректно поставить тип `LOAD`, чтобы остальные ассоциации доставались по стратегии модели. Однако [с типом по умолчанию `FETCH` роли также достаются](https://stackoverflow.com/a/46013654/548473) (похоже что бага). + +#### Apply 7_06_HW6_optional_jdbc.patch +> - реализовал в `JdbcUserRepositoryImpl.getAll()` доставание ролей через лямбду +> - в `insertRoles` поменял метод `batchUpdate` и сделал проверку на empty + +Еще интересные JDBC реализации: + - в `getAll()/ get()/ getByEmail()` делать запросы с `LEFT JOIN` и сделать реализацию `ResultSetExtractor` + - подключить зависимость `spring-data-jdbc-core`. Там есть готовый `OneToManyResultSetExtractor`. Можно посмотреть, как он реализован. + - реализация, зависимая от БД (для postgres): доставать агрегированные роли и делать им `split(",")`: +``` +... +``` + +## Занятие 7: +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. Тестирование Spring MVC +#### Apply 7_07_controller_test.patch +> - в `MockMvc` добавился `CharacterEncodingFilter` +> - добавил `AllActiveProfileResolver` +> - реализация Ehcache нетранзакционная, после отката транзакции в тестах по `@Transactional` Hibernate кэш не восстанавливал роль для USER. Добавил очистку кэша Hibernate в `AbstractControllerTest.setUp` (с учетом того, что `Profiles.REPOSITORY_IMPLEMENTATION` можно переключить на `JDBC`). + +- Hamcrest +- Unit Testing of Spring MVC Controllers + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Миграция на JUnit 5](https://www.youtube.com/watch?v=YmLzT-j1hU4) +#### Apply 7_08_JUnit5.patch +> [No need `junit-platform-surefire-provider` dependency in `maven-surefire-plugin`](https://junit.org/junit5/docs/current/user-guide/#running-tests-build-maven) + +- [JUnit 5 homepage](https://junit.org/junit5) +- [Overview](https://junit.org/junit5/docs/snapshot/user-guide/#overview) +- [10 интересных нововведений](https://habr.com/post/337700) +- Дополнительно: + - [Extension Model](https://junit.org/junit5/docs/current/user-guide/#extensions) + - [A Guide to JUnit 5](http://www.baeldung.com/junit-5) + - [Migrating from JUnit 4](http://www.baeldung.com/junit-5-migration) + - [Before and After Test Execution Callbacks](https://junit.org/junit5/docs/snapshot/user-guide/#extensions-lifecycle-callbacks-before-after-execution) + - [Conditional Test Execution](https://junit.org/junit5/docs/snapshot/user-guide/#writing-tests-conditional-execution) + - [Third party Extensions](https://github.com/junit-team/junit5/wiki/Third-party-Extensions) + - [Реализация assertThat](https://stackoverflow.com/questions/43280250) + + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 5. [Принципы REST. REST контроллеры](https://youtu.be/33_2yOck4ak) +#### Apply 7_09_rest_controller.patch + +- Понимание REST +- JSON (JavaScript Object Notation) +- [15 тривиальных фактов о правильной работе с протоколом HTTP](https://habrahabr.ru/company/yandex/blog/265569/) +- [10 Best Practices for Better RESTful](http://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/) +- [Best practices for rest nested resources](https://stackoverflow.com/questions/20951419/what-are-best-practices-for-rest-nested-resources) +- Request mapping +- Дополнительно: + - JAX-RS vs Spring MVC + - RESTful API для сервера – делаем правильно (Часть 1) + - RESTful API для сервера – делаем правильно (Часть 2) + - И. Головач. RestAPI + - [value/name в аннотациях @PathVariable и @RequestParam](https://habr.com/ru/post/440214/) + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 6. [Тестирование REST контроллеров. Jackson](https://drive.google.com/file/d/1aZm2qoMh4yL_-i3HhRoyZFjRAQx-15lO) +#### Apply 7_10_rest_test_jackson.patch +- [Jackson databind github](https://github.com/FasterXML/jackson-databind) +- [Jackson Annotation Examples](https://www.baeldung.com/jackson-annotations) + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 7. [Кастомизация Jackson Object Mapper](https://drive.google.com/file/d/1CM6y1JhKG_yeLQE_iCDONnI7Agi4pBks) + +#### Apply 7_11_jackson_object_mapper.patch +- Сериализация hibernate lazy-loading с помощью jackson-datatype-hibernate +- Handle Java 8 dates with Jackson +- Дополнительно: + - Jackson JSON Serializer & Deserializer + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 8. [Тестирование REST контроллеров через JSONassert](https://drive.google.com/file/d/1oa3e0_tG57E71g6PW7_tfb3B61Qldctl) +#### Apply 7_12_json_assert_tests.patch +- [JSONassert](https://github.com/skyscreamer/JSONassert) +- [Java Code Examples for ObjectMapper](https://www.programcreek.com/java-api-examples/index.php?api=com.fasterxml.jackson.databind.ObjectMapper) + +### ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 9. Тестирование через SoapUi. UTF-8 +#### Apply 7_13_soapui_utf8_converter.patch +- Инструменты тестирования REST: + - SoapUi + - Написание HTTP-запросов с помощью Curl +(для Windows можно использовать Git Bash). Для работы с UTF-8 в Windows 10 нужны пляски с бубном: ["Язык и региональные стандарты" -> "Сопутствующие параметры" -> "Административные языковые параметры" -> "Изменить язык системы" -> галка "Бета-версия:Использовать Юникод (UTF-8) для поддержки языка во всем мире"](https://drive.google.com/open?id=1J1WquTv9wenJQ9ptMymXPYGnrvFzAV-L), перезагрузка. + - Postman + - IDEA: Tools->HTTP Client->... + - [Insomnia REST client](https://insomnia.rest/) + +**Импортировать проект в SoapUi из config\Topjava-soapui-project.xml. Response смотреть в формате JSON.** + +> Проверка UTF-8: http://localhost:8080/topjava/rest/profile/text + +ResponseBody and UTF-8 + +## ![question](https://cloud.githubusercontent.com/assets/13649199/13672858/9cd58692-e6e7-11e5-905d-c295d2a456f1.png) Ваши вопросы +> При выполнении тестов через MockMvc никаких изменений на базе не видно, почему оно не сохраняет? + +`AbstractControllerTest` аннотируется `@Transactional` - это означает, что тесты идут в транзакции и после каждого теста JUnit делает rollback базы. + +> Что получается в результате выполнения запроса `SELECT DISTINCT(u) FROM User u LEFT JOIN FETCH u.roles ORDER BY u.name, u.email`? В чем разница в SQL без `DISTINCT`. + +Запросы SQL можно посмотреть в логах. Те `DISTINCT` в `JPQL` влияет на то, как Hibernate обрабатывает дублирующие записи (с `DISTINCT` их исключает). Результат можно посмотреть в тестах или приложении, поставив брекпойнт. +По поводу `SQL DISTINCT` не стесняйтесь пользоваться google, например [оператор SQL DISTINCT](http://2sql.ru/novosti/sql-distinct/) + +> В чем заключается расширение функциональности hamcrest в нашем тесте, что нам пришлось его отдельно от JUnit прописывать? + +hamcrest-all используется в проверках `RootControllerTest`: `org.hamcrest.Matchers.*` + +> Jackson мы просто подключаем в помнике и спринг будет с ним работать без любых других настроек? + +Да, Spring смотрит в classpath и, если видит там Jackson, то подключает интеграцию с ним + +> Где-то слышал, что любой ресурс по REST должен однозначно идентифицироваться через url, без параметров. Правильно ли задавать URL для фильтрации в виде `http://localhost/topjava/rest/meals/filter/{startDate}/{startTime}/{endDate}/{endTime}` ? + +Так делают, только при отношении агрегация. В случае критериев, поиска или страничных данных они передаются как параметр. Смотри также: +- [15 тривиальных фактов о правильной работе с протоколом HTTP](https://habrahabr.ru/company/yandex/blog/265569/) +- 10 Best Practices for Better RESTful + +> Что означает конструкция в `JsonUtil`: `reader.readValues(json)`; + +См. Generic Methods. Когда компилятор не может вывести тип, можно его уточнить при вызове generic метода. Не важно static или нет. + +## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Домашнее задание HW07 + +- 1: Добавить тесты контроллеров: + - 1.1 `RootControllerTest.testMeals` для `meals.jsp` + - 1.2 `ResourceControllerTest` для `style.css` (проверить status и ContentType) +- 2: Реализовать `MealRestController` и протестировать его через `MealRestControllerTest` + - 2.1 cледите чтобы url в тестах совпадал с параметрами в методе контроллера. Можно добавить логирование `` для проверки маршрутизации. + - 2.2 в параметрах `getBetween` принимать `LocalDateTime` (конвертировать через @DATETIMEFORMAT WITH JAVA 8 DATE-TIME API), а передавать в тестах в формате `ISO_LOCAL_DATE_TIME` (например `'2011-12-03T10:15:30'`). Вызывать `super.getBetween()` пока без проверки на `null`, используя `toLocalDate()/toLocalTime()` (см. Optional п.3) + +#### Optional +- 3: Переделать `MealRestController.getBetween` на параметры `LocalDate/LocalTime` c раздельной фильтрацией по времени/дате, работающий при `null` значениях (см. демо и `JspMealController.getBetween`). Заменить `@DateTimeFormat` на свои LocalDate/LocalTime конверторы или форматтеры. + - Spring Type Conversion + - Spring Field Formatting + - Difference between Spring MVC formatters and converters +- 4: Протестировать `MealRestController` (SoapUi, curl, IDEA Test RESTful Web Service, Postman). Запросы `curl` занести в отдельный `md` файл (либо `README.md`) + +**На следующем занятии используется JavaScript/jQuery. Если у вас там пробелы, пройдите его основы** + +--------------------- +## ![error](https://cloud.githubusercontent.com/assets/13649199/13672935/ef09ec1e-e6e7-11e5-9f79-d1641c05cbe6.png) Подсказки по HW07 +- 1: Ошибка в тесте _Invalid read array from JSON_ обычно расшифровывается немного ниже: читайте внимательно. +- 2: Jackson и неизменяемые объекты +- 3: Jackson JSON Tutorial +- 4: Если у meal, приходящий в контроллер, поля null, проверьте `@RequestBody` перед параметром (данные приходят в формате JSON) +- 5: При проблемах с собственным форматтером убедитесь, что в конфигурации ` Date: Thu, 28 Mar 2019 22:40:12 +0300 Subject: [PATCH 03/14] Update lesson07 --- README.md | 1 + doc/lesson07.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index d6e1d486e3b9..99c5d0835be0 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,7 @@ Java Enterprise Online Project - 12: Обращайте внимание на комментарии к вашим коммитам в git. Они должны быть короткие и информативные (лучше на english) - 13: Не полагайтесь в решении на то, что список будет подаваться отсортированным. Такого условия нет. ----- +## [Пример 7-го занятия онлайн стажировки, несколько видео открыто](https://github.com/JavaOPs/topjava/blob/master/doc/lesson07.md) ### Полезные ресурсы > ВНИМАНИЕ: diff --git a/doc/lesson07.md b/doc/lesson07.md index 7326f915dc06..2327d2e6bb53 100644 --- a/doc/lesson07.md +++ b/doc/lesson07.md @@ -1,4 +1,6 @@ # [Онлайн стажировка Spring 5/JPA Enterprise (Topjava)](http://javaops.ru/view/topjava) +# REST, REST контроллеры, тестирование Spring MVC контроллеров +## Седьмое занятие, несколько видео открыто. [Формат обучения на стажировке](http://javaops.ru/#format) ## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Разбор домашнего задания HW6 From f61784bac98b7d3c5342a0572eb81c5acd89e83d Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Fri, 29 Mar 2019 02:35:27 +0300 Subject: [PATCH 04/14] Update lesson07.md --- doc/lesson07.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/lesson07.md b/doc/lesson07.md index 2327d2e6bb53..9a59e0fda3d4 100644 --- a/doc/lesson07.md +++ b/doc/lesson07.md @@ -1,6 +1,11 @@ # [Онлайн стажировка Spring 5/JPA Enterprise (Topjava)](http://javaops.ru/view/topjava) -# REST, REST контроллеры, тестирование Spring MVC контроллеров -## Седьмое занятие, несколько видео открыто. [Формат обучения на стажировке](http://javaops.ru/#format) +## REST, REST контроллеры, тестирование Spring MVC контроллеров (несколько видео открыто) +## [Формат обучения на стажировке](http://javaops.ru/#format) +- Не стоит стремиться прочитать все ссылки урока, их можно использовать как справочник. Гораздо важнее пройти основной материал урока и сделать Домашнее Задание +- Обязательно посмотри правила работы с патчами на проекте +- Делать Apply Patch лучше по одному, непосредственно перед видео на эту тему, а при просмотре видео сразу отслеживать все изменения кода проекта по изменению в патче (`Version Control->Local Changes-> Ctrl+D`) +- При первом Apply удобнее выбрать имя локального ченджлиста Name: Default. Далее все остальные патчи также будут в него попадать. +- Код проекта обновляется и не всегда совпадает с видео (можно увидеть как развивался проект). Изменения в проекте указываю после соответствующего патча. ## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Разбор домашнего задания HW6 From adc2b0caa72ce92de851deccb22dabed162387a2 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 9 Apr 2019 23:50:08 +0300 Subject: [PATCH 05/14] Update ReleaseNotes.md --- ReleaseNotes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 5298ae94db76..07d5f1370c8d 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,4 +1,9 @@ # TopJava Release Notes +### Topjava 16 +- Выделил общий код реализации хранения в памяти в `InMemoryBaseRepositoryImpl` +- Сделал подтверждение для удаления записей +- Валидации дублирования записей сделал через `WebDataBinder` и `Validator` + ### Topjava 15 - Миграция на Servlet API 4.0 / Tomcat 9.x - [Миграция на JDK11](http://javaops.ru/view/resources/jdk8_11) From c61fe197d9c3c4e226fa7555818240c2a2d446dd Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Mon, 15 Apr 2019 02:46:47 +0300 Subject: [PATCH 06/14] Update ReleaseNotes.md --- ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 07d5f1370c8d..403a93e7146d 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,7 +2,7 @@ ### Topjava 16 - Выделил общий код реализации хранения в памяти в `InMemoryBaseRepositoryImpl` - Сделал подтверждение для удаления записей -- Валидации дублирования записей сделал через `WebDataBinder` и `Validator` +- Валидации дублирования записей в этом выпуске будем делать через `WebDataBinder` и `Validator` ### Topjava 15 - Миграция на Servlet API 4.0 / Tomcat 9.x From adf5fc506663858678d74ded144010f2a5e075b9 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Mon, 15 Apr 2019 02:47:35 +0300 Subject: [PATCH 07/14] Update ReleaseNotes.md --- ReleaseNotes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 403a93e7146d..7b60e3fcdbc3 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -3,6 +3,7 @@ - Выделил общий код реализации хранения в памяти в `InMemoryBaseRepositoryImpl` - Сделал подтверждение для удаления записей - Валидации дублирования записей в этом выпуске будем делать через `WebDataBinder` и `Validator` +- Отдельно сделаем патч на адаптивный дизайн UI. ### Topjava 15 - Миграция на Servlet API 4.0 / Tomcat 9.x From cdf82e27206c394aa4ac4b21b1de9f324bf7baef Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Mon, 15 Apr 2019 02:50:06 +0300 Subject: [PATCH 08/14] Update ReleaseNotes.md --- ReleaseNotes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 7b60e3fcdbc3..720374469301 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,7 @@ ### Topjava 16 - Выделил общий код реализации хранения в памяти в `InMemoryBaseRepositoryImpl` - Сделал подтверждение для удаления записей +- Обновились видео 7-го занятия. [Выложил его как пример занятия, некоторые видео открыты](https://github.com/JavaOPs/topjava/blob/master/doc/lesson07.md) - Валидации дублирования записей в этом выпуске будем делать через `WebDataBinder` и `Validator` - Отдельно сделаем патч на адаптивный дизайн UI. From 13edb889a5f3673b048555434830853dc4079d9a Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 25 Apr 2019 02:51:48 +0300 Subject: [PATCH 09/14] Update ReleaseNotes.md --- ReleaseNotes.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 720374469301..ae142c42357e 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -3,8 +3,7 @@ - Выделил общий код реализации хранения в памяти в `InMemoryBaseRepositoryImpl` - Сделал подтверждение для удаления записей - Обновились видео 7-го занятия. [Выложил его как пример занятия, некоторые видео открыты](https://github.com/JavaOPs/topjava/blob/master/doc/lesson07.md) -- Валидации дублирования записей в этом выпуске будем делать через `WebDataBinder` и `Validator` -- Отдельно сделаем патч на адаптивный дизайн UI. +- Сделали валидации дублирования email через `WebDataBinder` и `Validator` ### Topjava 15 - Миграция на Servlet API 4.0 / Tomcat 9.x From 64217e542a106e388a9c39417dccdd681e302f94 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 9 May 2019 23:13:43 +0300 Subject: [PATCH 10/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99c5d0835be0..6d46c4df57e9 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ Java Enterprise Online Project ### Полезные ресурсы > ВНИМАНИЕ: -> - ДЗ первого урока будет связано с созданием небольшого CRUD приложения (в памяти, без DB) на JSP и сервлетах. Введение будет, но предварительное знакомство не помешает. +> - **ДЗ первого урока будет связано с [созданием небольшого CRUD приложения (в памяти, без DB) на JSP и сервлетах](https://danielniko.wordpress.com/2012/04/17/simple-crud-using-jsp-servlet-and-mysql/)**. Введение будет, но предварительное знакомство не помешает. > - основы JavaSсript необходимы для понимания проекта, начиная с 8-го занятия! Все остальное - опционально. From 7ba51b04acc8625e175ab70678b2911ba114c6dc Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 9 May 2019 23:14:17 +0300 Subject: [PATCH 11/14] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6d46c4df57e9..de83d87b4911 100644 --- a/README.md +++ b/README.md @@ -174,8 +174,8 @@ Java Enterprise Online Project - A Guide to Java 8 ### Туториалы, разное -[Что нужно знать о бэкенде новичку в веб-разработке](https://tproger.ru/translations/backend-web-development) -[Туториалы: Spring Framework, Hibernate, Java Core, JDBC](http://proselyte.net/tutorials/) +- [Что нужно знать о бэкенде новичку в веб-разработке](https://tproger.ru/translations/backend-web-development) +- [Туториалы: Spring Framework, Hibernate, Java Core, JDBC](http://proselyte.net/tutorials/) #### Сервлеты - Как создать Servlet? Полное руководство. From 4a857f2aa8e92a7d6204c337e76e32ff033dd3b4 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 22 May 2019 18:02:25 +0300 Subject: [PATCH 12/14] Update graduation.md --- graduation.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/graduation.md b/graduation.md index f167155ab997..2541d69cd9a1 100644 --- a/graduation.md +++ b/graduation.md @@ -67,7 +67,9 @@ _Антуан де Сент-Экзюпери_ - 23: Если используете кэширование, **тщательно продумайте, что надо кэшировать (самые частые запросы)**, а что нет (большие или редкозапрашиваемые данные)! ## Попробуйте подергать свое API по всем типичным сценариям ТЗ! -- Удобно использовать? Можно сделать проще? Например чтобы проголосовать за ресторан залогиненному юзеру достаточно `restorauntId`. -- Удовлетворяет ли принципам REST (см. ссылки выше)? +- Удобно использовать? Можно сделать проще? *Например чтобы проголосовать за ресторан залогиненному юзеру достаточно `restorauntId`.* - Сколько раз пришлось его вызвать API для типичного сценария (нарпимер посмотреть рестораны с едой)? - Сколько запросов к базе было сделано? Можно ли сократить (например с FETCH/Graph или через кэширование)? +- **API ДОЛЖНО соответствовать принципам REST (см. ссылки выше)** +- **ОБЯЗАТЕЛЬНО: запустите `mvn test`- ошибок быть не должно*** +- **ОБЯЗАТЕЛЬНО: запустите приложение без всяких предварительных настроек (базы, переменных окружения, ..), лучше на другом компьютере. Должно запускаться!** From 046e67b010aaabd870a01a55615f52a36e34bc92 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 22 May 2019 18:02:59 +0300 Subject: [PATCH 13/14] Update graduation.md From 562d53dc2411bf758faf5b0208540839cb24f028 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 22 May 2019 18:04:31 +0300 Subject: [PATCH 14/14] Update graduation.md --- graduation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graduation.md b/graduation.md index 2541d69cd9a1..6aee3f6ed695 100644 --- a/graduation.md +++ b/graduation.md @@ -71,5 +71,5 @@ _Антуан де Сент-Экзюпери_ - Сколько раз пришлось его вызвать API для типичного сценария (нарпимер посмотреть рестораны с едой)? - Сколько запросов к базе было сделано? Можно ли сократить (например с FETCH/Graph или через кэширование)? - **API ДОЛЖНО соответствовать принципам REST (см. ссылки выше)** -- **ОБЯЗАТЕЛЬНО: запустите `mvn test`- ошибок быть не должно*** +- **ОБЯЗАТЕЛЬНО: запустите `mvn test`- ошибок быть не должно** - **ОБЯЗАТЕЛЬНО: запустите приложение без всяких предварительных настроек (базы, переменных окружения, ..), лучше на другом компьютере. Должно запускаться!**