Честно говоря, особого желания нет копаться до истины и "а почему же всё-таки так", но случай интересный.
История возникновения
На странице, куда осуществляется редирект после некорректного логина было несколько контролов (в моём случае h:link на попробовать ещё раз и на страницу восстановления пароля). Страница очень простая, никаких аяксов, лишь эти 2 ссылки и статический текст о том, что авторизация не удалась.
Запускаем, вводим неверный пароль, вместо страницы ошибки входа видим в браузере internal server error 500, а в логе:
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.RangeCheck(ArrayList.java:547) at java.util.ArrayList.get(ArrayList.java:322) at javax.faces.component.AttachedObjectListHolder.restoreState(AttachedObjectListHolder.java:165) at javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:1560)А если не поленимся обновить страницу, то всё отобразится корректно.
Кто виноват и что делать?
Оказалось, всё дело в том, что стандартный j_security_check request обрабатывается напрямую веб-контейнером, а не JSF. Собственно, это не секрет, секрет в том, что из этого следует: на странице ошибки входа JSF не сгенерирует id-шников для контролов. Поэтому всё, что нужно, это явно указать идентификаторы:
...
try login again
restore your password
Почему после обновления страницы всё работает?
Потому что это будет обычный запрос "файла с хтмл" на сервере, а не j_security_check, поэтому его обработает движок JSF.
Почему такой странный лог restoreState : IndexOutOfBoundsException, если всё дело в идентификаторах контролов?
Не знаю, как раз в этом разбираться у меня желания не было. Надеюсь, разработчики это пофиксят со временем.
Комментариев нет:
Отправить комментарий