diff --git a/README.md b/README.md new file mode 100644 index 000000000000..786ec1b557bb --- /dev/null +++ b/README.md @@ -0,0 +1,106 @@ +Java Enterprise Online Project +=============================== +Наиболее востребованные технологии /инструменты / фреймворки Java Enterprise: +Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + plugins. + + Когда вы слышите что-то, вы забываете это. + Когда вы видите что-то, вы запоминаете это. + Но только когда вы начинаете делать это, + вы начинаете понимать это + + Старинная китайская поговорка + +## Описание и план проекта +### Демо разрабатываемого приложения +### Требования к участникам, Wiki + +Вводное занятие +=============== +## ![video](http://s.ytimg.com/yts/img/favicon-vflz7uhzw.ico) Системы управления версиями. Git. + +- Система управления версиями. VCS/DVSC. +- Ресурсы: + - Интерактивная Git обучалка + - Основы Git + - Working with remote repositories + - Видео по обучению Git + - Как начать работать с GitHub: быстрый старт + - Справочник в графическом виде + - Git Overview + - Видеокурс по Git + +## ![video](http://s.ytimg.com/yts/img/favicon-vflz7uhzw.ico) Работа с проектом (выполнять инструкции) +- **Prepare_ to_ HW0.patch (скачать и положить в каталог вашего проекта)** +- Доступно о Java 8 Lambda + +## Инструкция по шагам (из видео): +- Установить ПО (git, JDK8, IntelliJ IDEA, Maven) +- Создать аккаунт на GitHub +- Сделать Fork ЭТОГО проекта (https://github.com/JavaOPs/topjava) +- Сделать локальный репозиторий проекта: +
git clone https://github.com/[Ваш аккаунт]/topjava.git
+- Открыть и настроить проект в IDEA +- По ходу видео сделать Apply Patch... скаченного патча Prepare_ to_ HW0.patch +- Закоммитить и запушить изменения (commit + push) +- Сделать ветку домашнего задания +- Выполнить задание и залить на GitHub (commit + push) +- Переключиться в основную ветку проекта master. + +## Домашнее задание HW0 + +- Java 8 Date and Time API +- Time complexity +- Временная сложность алгоритма +- Вычислительная сложность +``` +Реализовать UserMealsUtil.getFilteredMealsWithExceeded: +- должны возвращаться только записи между startTime и endTime +- поле UserMealWithExceed.exceed должно показывать, + превышает ли сумма калорий за весь день параметра метода caloriesPerDay + +Т.е UserMealWithExceed - это запись одной еды, но поле exceeded будет одинаково для всех записей за этот день. + +- Проверте результат выполнения ДЗ (можно проверить логику в http://topjava.herokuapp.com , список еды) +- Оцените Time complexity вашего алгоритма (если он O(N*N)- попробуйте сделать O(N). +``` +Optional + +- Java 8: Lambda выражения +- Java 8: Потоки +- Pуководство по Java 8 Stream +- Лямбда-выражения в Java 8 +- Шпаргалка Java Stream API +- stream.map vs forEach + +``` +Сделать реализация через Java 8 Stream API. Заменяйте forEach оператором stream.map(..) +``` +### Составление резюме, подготовка к интервью, поиск работы +### Ресурсы для подготовки к проекту +#### (желательно иметь представление для лучшего усвоения материала) + +#### Java Web (Servlets, JSP) +- Введение в сетевое программирование +- Основы Java на реальном примере (Servlets, JSP) +- Как создать Servlet? Полное руководство. +- Технологии Java для разработки веб-приложений + +#### HTML, JavaScript, CSS +- Основы работы с HTML/CSS/JavaScript +- jQuery для начинающих +- Уроки Bootstrap 3 + +#### Java Core (Reflection API, JUnit) +- Введение в Java Reflection API +- Java JUnit + +#### JDBC, SQL +- Уроки по JDBC +- Learn SQL +- Try SQL + +#### Разное +- Интуит. Программирование на Java +- Oracle Java tutorial на русском. +- Эффективная работа с кодом в IntelliJ IDEA diff --git a/cv.md b/cv.md new file mode 100644 index 000000000000..95a53c28f61a --- /dev/null +++ b/cv.md @@ -0,0 +1,55 @@ +## Составление резюме, подготовка к интервью, поиск работы + +![cv](https://cloud.githubusercontent.com/assets/13649199/10877471/93ea86b8-8157-11e5-9bfa-95e3fba75c58.jpg) + +- Научиться программировать сложнее, чем кажется + +### Составление резюме: +- Идеальное резюме Junior’а +- Как продать свое резюме в 2 раза дороже +- Как правильно составить резюме +- Резюме программистов. Часть 1 (плохие) +- Резюме программистов. Часть 2 (хорошие) +- Как составить резюме на английском + +### Интервью: +- Михаил Портнов. Собеседование на работу: как продать себя грамотно +- Михаил Портнов. Какие вопросы мы задаем на собеседовании? +- Канал: Резюме, поиск работы, интервью +- Яков Файн: Как стать профессиональным Java разработчиком +- Quizful- тесты онлайн +- Сборка по вопросам на интервью +- Тест на знание SQL +- Сборка вопросов от 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: +- После завершения проекта вы освоите все заявленные в нем технологии - вставьте в квалификацию (включая 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. + - отлично будет, если вы его еще как то сами доработаете + +- По поводу обучения на курсах- можно упомянуть в разделе образования. Но на собеседовании меньше смотрят на то, что вы заканчивали, больше - на ваш опыт и то что вы знаете. + +### В течении проекта заполните форму соискателя "Разработчик Java" +Я ее рассылаю всем знакомым HR, уже есть пинги и трудоустройство. + +### Основные сайты поиска работы: +- HH +- LinkedIn +- djinni.co (более актуально для Украины) +- moikrug diff --git a/description.md b/description.md new file mode 100644 index 000000000000..cbb102fa72aa --- /dev/null +++ b/description.md @@ -0,0 +1,67 @@ +#### Разработка полнофункционального 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 +- Основное внимание будет уделяться способам решения многочисленных проблем разработки в Spring/JPA, а также структурному (красивому и надежному) java кодированию и архитектуре приложения. +- Каждая итерация проекта в закрепляется домашним заданием по реализации схожей функциональности. Следующее занятие начинается с разбора домашних заданий. +- Большое внимание уделяется тестированию кода: в проекте 88 JUnit тестов. +- Несмотря на относительно небольшой размер, приложение разрабатывается с нуля как большой проект (например мы используем кэш 2-го уровня Hibernate, настраиваем Jenkins для работы с ленивой загрузкой +Hibernate, делаем конверторы для типов LocalDateTime (Java 8 time API), которые еще не поддерживаются ни JPA/Hibernate, ни Jackson/json). + Разбираются архитектурные паттерны: слои приложения и как правильно разбивать логику по слоям, когда нужно применять 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. +- Поддержка 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. Datatables. +- AJAX. jQuery. Notifications. +- Spring Security +- Spring Binding/Validation +- Работа с Datatables через Ajax. +- Spring Security Test +- Encoding password +- CSRF (добавление в проект защиты от межсайтовой подделки запроса) +- form-login. Spring Security Taglib +- Handler interceptor +- Spring Exception Handling +- Деплой в Heroku diff --git a/lesson01.md b/lesson01.md new file mode 100644 index 000000000000..30f1c519a7b1 --- /dev/null +++ b/lesson01.md @@ -0,0 +1,177 @@ +# Занятие 1 онлайн проекта Topjava + +- **Напоминаю, что cвой код пишете только в ветках HWxx. Код в ветке MASTER трогать нельзя! +Модификация кода только через патчи в материалах урока (Apply Patch), иначе придется мержить код. +Все патчи объязательны и применяются по порядку. Если при применении патча предлагается мержд, cмотрите GIT Wiki, Patch не накатывается.** + +- **Делать Apply Patch лучше по одному непосредственно перед видео на эту тему - тогда при просмотре вы сразу сможете отслеживать изменения кода проекта.** + +- **Код проекта постоянно модифицируется, поэтому в видео вы можете увидеть старую версию кода. Иногда это способствует лучшему пониманию кода и вы видете, каким образом проект развивался** + +- **Не надо подробно читать все ссылки занятия, иначе времени не останется на ДЗ, что гораздо важнее. Пусть ссылки будут Вашим справочником, к которым вы в любое время можете обратиться.** + +- **Подсказка по работе с патчами (GIT Wiki)** + +## Материалы урока + +## HW0 (Optional): реализация getFilteredMealsWithExceeded через Stream API +- **1-1-HW0-stream.patch** + +## Работа с git в IDEA. HW0: реализация через цикл. +- **1-2-HW0-cycle.patch** + +> Изменения в проекте: `map.getOrDefault` земенил на `map.merge`, `for` заменены на `forEach` + +## Обзор используемых в проекте технологий. Интеграция ПО. +- Обзор популярности инструментов и технологий Java за 2014 г. +- Видео "Приложение Spring Pet Clinic" +- Приложение Spring Pet Clinic. +- Demo Spring Pet Clinic + +## Maven. +- Среда сборки проектов Maven. +- The Central Repository +- Настройка пропертей Maven: кодировка, java version, зависимости, maven-compiler-plugin +- The Reactor. Snapshots +- Недостатки Maven. Другие инструменты сборки. +- Справочник: + - Автоматизация сборки проекта + - Home Page + - Maven: The Complete Reference + - Разработка ПО вместе с maven + - Build Lifecycle + - Dependency Mechanism + - Создание своих архетипов и каталогов в Maven + - Зависимости, профили + - Bintray: gateway to Maven Central + +## WAR. Веб-контейнер Tomcat. Сервлеты. +- **1-3-switch-to-war.patch** +> Сервлет добавляется в следующем патче, те в web.xml он будет подчеркиваться красным. + +- **1-4-add-servlet-api.patch** +- **1-5-forward-to-redirect.patch** + +- Перевод проекта на Web. +- Tomcat Home Page +- Сервлеты. +- Настройка и деплой в Tomcat. Tomcat manager. Remote debug. +- Запуск Tomcat из IDEA. Динамическое обновление без передеплоя. +- Redirect, Forward, Application context, Servlet context + - Томкат менеджер: http://localhost:8080/manager + - Наше приложение: http://localhost:8080/topjava + - Наш сервлет: http://localhost:8080/topjava/users + +- Справочник: + - Отладчик IntelliJ IDEA + - Yakov Fain: Intro to Java EE. Glassfish. Servlets (по русски) + - Yakov Fain: HTTP Sessions, Cookies, WAR deployments, JSP (по русски) + - Golovach Courses: Junior.February2014.Servlets + - Технологии Java для разработки веб-приложений + - Remotely debug on tomcat from IDEA + +## Логирование. +- **1-6-logging.patch** +> **установите переменную окружения на TOPJAVA_ROOT на корень проекта и перезапустите IDEA** + +> изменения в проекте: убрал `LoggerWrapper` и логирую напрямую в логгер SLF4J. При логгировании через вспомогательный класс, в логе теряется имя исходного класса. + +- Java Logging: история кошмара +- Ведение лога приложения +- Log4j, Logback +- Добавление зависимостей логирования в проект. Переменная окружения TOPJAVA_ROOT +- Конфигурирование логирования. Настройка Live Template. +- Тестирование логирования в сервлете. + +### Проверочные вопросы: +- Что нужно изменить в `pom.xml`, чтобы перейти с logback на log4j ? + +## Дополнительно +### Подсоединение к логгеру по JMX. Выбор работы. +- **1-7-remote-jmx.patch** + +> Для подключения к Remote Process (`localhost:1099`) положить `setenv.bat` в `$TOMCET_HOME/bin`. + +- Управление логированием по Java Management Extensions. + +## Домашнее задание (делаем ветку HW01 от последнего патча) + + По аналогии с Users добавить MealServlet и mealList.jsp. + Задеплоить приложение (war) в Tomcat c applicationContext=topjava + Попробовать разные деплои в Tomcat, remote и local debug + + Сделать отображения списка еды в jsp, цвет записи в таблице зависит от параметра isExceeded (красный/зеленый). + Вариант реализации: + - из сервлета обращаетесь к реализации хранения еды в памяти; + - преобразуете результат в List; + - кладете список в запрос (request.setAttribute); + - делаете forward на jsp для отрисовки таблицы (при redirect аттрибуты теряются). + В jsp для цикла можно использовать JSTL tag forEach. + + Для подключения `JSTL` в `pom.xml` нужно добавить зависимость: + + + javax.servlet + jstl + 1.2 + + +- Ресурсы: + - Интернет-приложения на JAVA + - HTTP 1.0 vs 1.1 + - JSP + - JSTL для написания JSP страниц + - JSTL: Шаблоны для разработки веб-приложений в java + +Optional + + Сделать В ПАМЯТИ (HashMap) реализацию CRUD (create/read/update/delete) для списка еды. + В качестве ключа добавить id в UserMeal/ UserMealWithExceed. + AJAX/JavaScript использовать не надо, делаем через
и doPost() в сервлете. + + +--------- + +### Ваши вопросы + +> Используются ли еще где-то в реальной разработке JSP, или это уже устаревшая технология? Заменит ли ее JSF (https://javatalks.ru/topics/38037)? + +JSF и JSP- разные ниши и задачи. +JSP- шаблонизатор, JSF- МVС фреймворк. Из моего опыта- с JSP сталкивался в 60% проектов. Его прямая замена: http://www.thymeleaf.org, но пока встречется достаточно редко. JSP не умирает, потому что просто и дешево. Кроме того включается в любой веб-контейнер (в Tomcat его реализация Jasper) + +JSF- sun-овский еще фреймворк, с которым я ни разу не сталкивался и особого желания нет. Вот он как раз, по моему мнению, активно замещается хотябы angular. + + +> А зачем мы использовали logback? Почему SLF4J нас не устроило? Почему реализация логирования не log4j? + +В `slf4j-api` это API. Там есть только пустая реализация `org.slf4j.helpers.NOPLogger` (можно посмотреть в исходниках). +Logback для новых проектов стал стандарт. spring-petclinic и spring-boot используют его. http://logback.qos.ch/reasonsToSwitch.html + +### Решение проблем + +- Если вы не попадаете на страничку/брекпойнт в сервлете: + - внимательно проверьте url и applicationContext (Application Context должен быть тот же, что и url приложения): https://github.com/JavaOPs/topjava/wiki/IDEA + - деплоить лучше как war exploded: просто нет упаковки в war и при нажатой кнопке `Update Resources on Frame Deactivation` можно обновляться css, html, jsp без передеплоя. При изменении web.xml, добавлении методов, классов необходим redeploy. + - посомтрите в task manager: возможно у вас запущено несколько JVM и они мешают друг другу. + +- Проблемы с кодировкой в POST. Возможное решение: +``` +protected void doPost(HttpServletRequest request, ...) { + request.setCharacterEncoding("UTF-8"); +``` + +- Пробелема с maven зависимостью: иногда помогает удаление закаченного артифакта из локального maven репозитория (посмотреть его расположение можно в Maven Settings) и Reimport (последняя и первая кнопка в Maven Projects). + +- Для работы с JSTL кроме добавления зависимости в `pom.xml` не забываем добавлять в шапку JSP: +``` +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +... +``` + +---------------------------- + +### Подсказки по HW01 (лучше сначала сделать самостоятельно, а потом проверить) + +- Хранение в `HashMap` - одна из наших реализаций (такжен будет jdbc, jpa и data-jpa). Т.е. с ней лучше работать через интерфейс, который не должен ничего знать о деталях реализации (Map, DB или что-то еще). +- Хранить нужно `UserMeal` и конвертировать ее в `UserMealWithExceed` когда отдаем список на отображение в JSP. Иначе при редактировании любой записи или изменении юзером своей нормы `caloriesPerDay` нужно будет пересчитывать все записи юзера. +- Стили `color` можно применять ко всей строке таблицы `tr`, а не каждой ячейке. 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..fde5448b93d8 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java @@ -0,0 +1,33 @@ +package ru.javawebinar.topjava.model; + +import java.time.LocalDateTime; + +/** + * GKislin + * 11.01.2015. + */ +public class UserMeal { + protected final LocalDateTime dateTime; + + protected final String description; + + protected 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/UserMealWithExceed.java b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java new file mode 100644 index 000000000000..dab6c9468c5e --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java @@ -0,0 +1,24 @@ +package ru.javawebinar.topjava.model; + +import java.time.LocalDateTime; + +/** + * GKislin + * 11.01.2015. + */ +public class UserMealWithExceed { + protected final LocalDateTime dateTime; + + protected final String description; + + protected final int calories; + + protected final boolean exceed; + + public UserMealWithExceed(LocalDateTime dateTime, String description, int calories, boolean exceed) { + this.dateTime = dateTime; + this.description = description; + this.calories = calories; + this.exceed = exceed; + } +} 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..02399b7288cf --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java @@ -0,0 +1,13 @@ +package ru.javawebinar.topjava.util; + +import java.time.LocalTime; + +/** + * GKislin + * 07.01.2015. + */ +public class TimeUtil { + public static boolean isBetween(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..2cb426400fa5 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java @@ -0,0 +1,35 @@ +package ru.javawebinar.topjava.util; + +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.model.UserMealWithExceed; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.util.Arrays; +import java.util.List; + +/** + * GKislin + * 31.05.2015. + */ +public class UserMealsUtil { + public static void main(String[] args) { + List mealList = Arrays.asList( + new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,10,0), "Завтрак", 500), + new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,13,0), "Обед", 1000), + new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,20,0), "Ужин", 500), + new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,10,0), "Завтрак", 1000), + new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,13,0), "Обед", 500), + new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,20,0), "Ужин", 510) + ); + getFilteredMealsWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12,0), 2000); +// .toLocalDate(); +// .toLocalTime(); + } + + public static List getFilteredMealsWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { + // TODO return filtered list with correctly exceeded field + return null; + } +}