-
Notifications
You must be signed in to change notification settings - Fork 35
Lesson 8
Онлайн проекта Topjava
- Браузер кэширует javascript и css. Если изменения не работают, обновите приложение в браузере (в хроме
Ctrl+F5) - При удалении файлов не забывайте делать clean:
mvn clean
- Небольшая правка кода
- Рефакторинг тестов
RootControllerTest: вместо сравнения по полям можно использовать нашUserTestData.assertMatchс помощьюAssertionMatcherадаптера. Методы сравнения по полям вhamcrest-allбольше не нужны, заменил наhamcrest-core.- Вместо сериализации ожидаемых объектов в json и сравнение с ответом в MVC через
content().json()красивее десериализовать ответ в объект и сравнивать уже объекты через нашиassertMatchc учетом игнорируемых полей.jsonassertстановится не нужен.
1. HW7
В
RootControllerTest.testMeals()сделал проверку черезmodel().attribute("meals", expectedValue). Сравнение происходит черезMealTo.equals(), который мы можем переопределить, т.к. он Transfer Object, не является сущностью (Entity).
-
Persistent classes implementing equals and hashcode: переопределять
equals()/hashCode()необходимо, если- использовать Entity в
Set(рекомендовано для many ассоциаций), либо как ключи вHashMap - использовать reattachment of detached instances (те манипулировать одним Entity в нескольких транзакциях/сессиях).
- использовать Entity в
- Оптимально использовать уникальные неизменяемые бизнес поля, но обычно таких нет, и, чаще всего, используются PK с ограничением, что он может быть
nullу новых объектов и нельзя объекты сравнивать черезequalsв бизнес-логике (например тестах). Equals() and hashcode() when using JPA and Hibernate
- Как и для юзера сериализуем json ответ контроллера и сравниваем через
ResultMatcher. ДляMealToиспользуем в сравненииisEqualTo.
2. HW7_Optional
Перенес форматтеры в подпакет
web, тк они используются Spring MVC
Добавил примеры запросов curl в
config/curl.md
- Написание HTTP-запросов с помощью Curl (для Windows можно использовать Git Bash)
- Обновил jQuery до 3.x, Bootstrap до 4.x
- УБРАЛ из проекта Dandelion обертку к datatables:
- не встречал нигде, кроме Spring Pet Clinic;
- поддержка работы с datatables через Dandelion оказалось гораздо более трудоемкое, чем работа с плагином напрямую.
- Исключил из зависимостей webjars ненужные jQuery
- Подключение веб ресурсов. WebJars.
- Introducing WebJars
- Document Object Model (DOM)
- What is the DOM?
- jQuery
- Is jquery a javascript library or framework
- DataTables
- Working with jQuery DataTables
4. Bootstrap
- Мигрировали на Bootstrap 4
- Добавил Font Awesome
- В таблице удаление/редактирование сделал без кнопок (линками)
- Bootstrap
- Дополнительно
JSP полезны, если надо с сервера отдать статический html с серверной логикой (условия, циклы), сформированный на основе модели. Для динамической отрисовки таблицы мы будем использовать REST и JSON на 9м уроке (работа с datatables через Ajax).
- Переименовал js скрипты по javascript filename naming convention
- Сделал загрузку скриптов асинхронной (и все общие скрипты в
headTag.jsp). Для асинхронной загрузки вынес скрипт изusers.jspвtopjava.users.js.- Добавил
dataTables.bootstrap4.js/css- Вместо id и селектора для добавления пользователя и сохранения формы использовал обработчик событий
onclickreset()не чистит скрытые (hidden) поля формы. Сделал очистку полей черезform.find(":input").val("")- Обновил dataTables API:
- Поменял форматирование модального окна: Botstrap4 Modal
- AJAX.
- Событие $(document).ready.
- jQuery для всех.
- jQuery для начинающих. AJAX.
- jQuery для начинающих. Селекторы.
- jQuery task from freecodecamp
- jQuery API
- Javascript плагины для Bootstrap
- DataTables API
- Заменил
varнаlet/const(в IDEA нужно поменять версию JavaScript черезAlt+Enter). Синтакс поддерживается 95% браузеров. На каждом конкретном проекте поддерживаемые версии браузеров определяются бизнесом.- В
jquery.ajaxзаменил depricatedsuccessнаdone()
- Сделал защиту от кэширование ajax запросов в IE
- Обновил API Noty (3.x), добавил в сообщения font-awesome
- Tomcat 8.5.x перестал отдавать в заголовке
statusText. Отображаем простоstatus
- RFC 7230 states that clients should ignore reason phrases in HTTP/1.1 response messages.
- Since the reason phrase is optional, Tomcat no longer sends it (statusText).
- Правка к видео: путь в intercept-url должен быть полный:
pattern="/rest/admin/**"- В Spring Security 4.x по умолчанию включен csrf (защита от межсайтовой подделки запроса). Выключил, включим на 10-м занятии.
- В Spring Security 5.x по умолчанию пароль кодируется. Выключил, включим на 10-м занятии.
почему для
spring-securityверсия не `${spring.version}' (5.1.2.RELEASE) ?
- Spring Security
- Протокол AAA
- Методы аутентификации.
- Basic access authentication
- Использование ThreadLocal
- Security with Spring
- Decode/Encode Base64 online
curl -v -H 'Authorization: Basic dXNlckB5YW5kZXgucnU6cGFzc3dvcmQ=' http://localhost:8080/topjava/rest/profile/meals
аналогична
curl -v --user [email protected]:password http://localhost:8080/topjava/rest/profile/meals
Что делает код?
$('.delete').click(function () {
deleteRow($(this).attr("id"));
});
На все элементы DOM с классом delete вешается обработчик события click который вызывает функцию deleteRow. Классы в html разделяются через пробел. См. селекторы в jQuery
тянет ли bootstrap за собой jQuery?
Bootstrap css это стили (форматирование), Bootstrap js зависит от jQuery: http://stackoverflow.com/questions/14608681/can-i-use-twitter-bootstrap-without-jquery#answer-14608772
А где реально этот путь "classpath:/META-INF/resources/webjars"?
Внутри подключаемых webjars ресурсы лежат по пути /META-INF/resources/webjars/... Не поленитесь посмотреть на них через Ctrl+Shift+N.
Все подключаемые jar попадают в classpath и ресурсы доступны по этому пути.
У меня webjars зависимость лежит внутри ".m2\repository\org\webjars". С чем это может быть связано?
Maven скачивает все депенденси в local repository, который по умолчанию находится в ~/.m2.
Каталог по умолчанию можно переопределить в APACHE-MAVEN-HOME\conf\settings.xml, элемент localRepository.
WEBJARS лежат вообще в другом месте WEB-INF\lib*. Биндим mapping="/webjars/*" на реальное положение jar в ware, откуда spring знает где искать наш jquery ?
В war в WEB-INF/lib/* лежат все jar, которые попадают к classpath. Spring при обращении по url /webjars/ ищет по пути биндинга <mvc:resources mapping="/webjars/ " location="classpath:/META-INF/resources/webjars/"/>
по всему classpath (то же самое как распаковать все jar в один каталог) в META-INF/resources/webjars/. В этом месте во всех jar, которые мы подключили из webjars лежат наши ресурсы.
Как можно в браузере сбросить введенный пароль базовой авторизации?
Проще всего делать новый запрос в новой анонимной вкладке (Ctrl+Shift+N в Chrome)
Оптимально ли делать доступ к статическим ресурсам (css, js, html) через webjars ?
На продакшене под нагрузкой статические ресурсы лучше всего держать не в war, а снаружи. Доступ к ним делается либо через конфигурирование Tomcat, но чаще всего через прокси, например Nginx
Как по REST определяется залогиненный юзер? Аутентификация происходит при каждом запросе?
Способы RESTful Authentication. Мы будем использовать 2: coockie + http session (на след. уроке) и Basic Authentication с аутентификацией при каждом запросе.
Почему
@RequestParamне работает в PUT и DELETE запросах?
По спецификации Servlet API параметры в теле для PUT, DELETE, TRACE методах не обрабатываются (только в url). Те. можно:
- использовать POST
- передавать параметры в url
- использовать
HttpPutFormContentFilterфильтр - настроить Tomcat в обход спецификации.
См. Handle request parameters for an HTTP PUT method
Данные между браузером и ajax гоняются в виде json? Почему в
AdminAjaxControllerу методов delete и createOrUpdate нет в аннотациях параметраconsumes = MediaType.APPLICATION_JSON_VALUE?
Посмотреть на данные между приложением и браузером можно (и нужно!) в браузере (вкладка Network в Инструментах разработчика, F12 в Хроме). Зависит от того, как их отправляем из браузера и из приложения. Данные формы обычно передаются просто параметрами. APPLICATION_JSON_VALUE в контроллере нужно, только если параметры отдаются/принимаются в формате JSON.
- 1: Перевести
mealsнаdatatables(meals.jsp,MealAjaxController).- 1.1 Реализовать добавление записи еды через модальное окно Bootstrap и удаление еды по ajax (БЕЗ редактирования).
- 1.2 При вставке данных по AJAX пропадает все JSP форматирование, чинить перерисовку НЕ надо. Следующий урок- будем делать datatable по AJAX и форматирование на стороне клиента.
- 2: Т.к. HTML атрибут id у каждого элемента документа должен быть уникален, нужно избавиться от дублирования
id="${user.id}"в строках таблиц users (users.jsp) (переместить атрибут id в тэг<tr>или передавать в качестве параметра функций черезonclick)
- 3: Перевести работу фильтра на AJAX. Попробуйте после модификации таблицы (например добавлении записи) обновлять ее также с учетом фильтра.
- 4: Сделать кнопку сброса фильтра.
- 5: Реализовать enable/disable User через checkbox в
users.jspс сохранением в DB. Неактивных пользователей выделить css стилем. Проверьте, как у вас первоначально (или по F5) отображаются неактивные пользователи (если меняете css при enable/disable)
- 1: enable/disable делать c
@Transactional(можно реализовать как на уровне репозитория, так и на уровне сервиса через несколько sql, которые должны быть в одной транзакции) - 2: в
topjava.common.jsследует выносите только общие скрипты (cкрипты еды размещайте вtopjava.meals.js, пользователей вtopjava.users.js) - 3: если в контроллер приходит
nullпроверте вNetworkвкладке браузера в каком формате приходят данные и в каком формате в контроллере вы их принимаете (consumes). - 4: при реализации
enable/disableлучше явно указывать нужное состояние, чем переключать на противоположное. Если параллельно вам кто-то изменит состояние, то будет несоответствие UI и DB. Не забудьте проenable/disableтесты.
Правка и рефакторинг
Разбор домашнего задания HW7
почему для