luchob/softuni-feb2023

Консултация

Closed this issue · 3 comments

Здравей Лъчо,
Няколко въпроса на веднъж:

  1. Появи се неочакван проблем. От време на време при опит за логване или регистрация гърми с тази грешка: 2023-03-30T07:52:45.431+03:00 ERROR 20732 --- [nio-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost] : Exception Processing ErrorPage[errorCode=0, location=/error]
    jakarta.servlet.ServletException: Unable to handle the Spring Security Exception because the response is already committed.
    В браузъра е този син екран:
    Screenshot_1
    След рестарт на браузъра, се оправя. Всъщност се получава след logout. Как да се справя с това?
  2. При Update на Home (ot MyHomes -> details -> edit) , както показваш ти - ако има грешка пренасочвам към /{id}/update/errors , от където трябва да ми върне наново формата. Но не ми я връща - стои си на /{id}/update/errors. И тази грешка: 2023-03-30T09:36:21.421+03:00 ERROR 25184 --- [nio-8080-exec-8] s.e.ErrorMvcAutoConfiguration$StaticView : Cannot render error page for request [/homes/4/update/errors] and exception [An error happened during template parsing (template: "class path resource [templates/update-home.html]")] as the response has already been committed. As a result, the response may have the wrong status code.
  3. Съвет относно Home Picture. Преди да покажеш клаудинари, имплементирах снимката след уплоад да се пази като име на файл, запазен в указан път. Уж разбирам какво правя, но явно не много. Нито мога да направя initHome, нито мога да тествам. Не разбирам как да подам на готово снимка освен чрез ъплоад-а. Също така опитите ми за интегрейшън тестове на addHome са безуспешни, тъй като не успявам да подам MultipartFile. Въпроса ми е дали да се опитам да преработя с Клаудинари или ако не ми стигне времето има някакъв начин да добавям снимките.
    Благодаря предварително.
luchob commented

Здравей!

Първият проблем е изключително интересен :-) Знам че искаш да ти кажа как да го оправиш, но ми позволи да ти го обясня, защото всичко става дълбоко под капака и това показва че трябва да си наясно с вътрешностите на системата. Да започваме!

Ей това наглед невинно нещичко (намира се на логин страницата, която вече не работи):

<form th:method="post"
          th:action="@{/users/login}"

Всъщност е много зло. :-)

Най-малкото, защото автоматично добавя скрит CSRF тоукън в HTML-a, показвал съм ви го. Добавя го докато си парсва темплейта... Но къде се пазят CSRF токъните за да работи цялата машинария изобщо? Ами... в сесията на потребителя. Ами ако няма сесия? Например след логаут?

                .invalidateHttpSession(true)
                .deleteCookies("JSESSIONID")

Или пък отвориш логина си в инкогнито браузър? Ами няма cookie, няма сесия, и сървърът ще я създаде при нужда и ще я върне към клиента в HTTP хедъра Cookie -> Няма проблем. Нали?

Всъщност има. Сървърът буферира response-a преди да го прати на браузъра. И в един момент (по подразбиране когато буфера достигне няколко... може би... 8К в байтове) той започва да го праща към клиента още преди Thymeleaf да завърши с парсването на темплийта. Само че почне ли да го изпраща към клиента, сървъра вече е пратил HTTP хедърите (в превод на английски -> the response is already committed) където би трябвало да е и JSESSIONID cookie-то. Т.е. вече е късно да се създаде сесия където Thymeleaf да запази тоукъна, просто защото няма как да съобщиш на браузъра номера на тази сесия в cookie (cookies вече пътуват).

При теб отначало е работило. Обаче си творила разни неща във фрагментите, коментирала си ги, пак си творила и коментирала и цялото чудо барабар с HTTP хедърите в един момент е набъбнало над размера на съврърния буфер. И точно около този момент е станало -> "Появи се неочакван проблем. "

Може да го адресираш като наредиш на Спринг винаги да създава сесия в началото, а не само при нужда:

                .and()
                    .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)

В mobilele-то няма такъв проблем, тъй като темплийта е много малък и не е творено достатъчно в него :-) А твоя е "набъбнал". Това може би решава и обяснява проблем 2.

Яко, нали? :-)

luchob commented

Здравей! Това с файловете в локалната файлове система ще ти е доста тегаво и неприятно, освен това няма да работи навсякъде, напр. ако решиш да го деплойваш.

С клаудинари е елементарно, според мен - дори бяхме правили някакви готови примери - пробвай тук -> https://github.com/luchob/softuni-spring-advanced-2021/tree/master/cloudinary

Или ако не става пък ги качи в ДБ? Пример -> https://github.com/luchob/fileupload
За някой от колегите го бях правил.

За тестове има един специален клас в спринг тест -> https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/mock/web/MockMultipartFile.html

Hint -> #46
Hint -> luchob/softuni-may2022#122

Поздрави,
Л.