Статьи

Пользовательские страницы ошибок для истекших разговоров с участием CDI и JSF

Прошло много времени с тех пор, как я последний раз писал в блоге. Я продолжаю думать о ведении блога на что-то техническое, но в итоге занимаюсь другими вещами. На прошлой неделе было очень интересное обсуждение на форумах Coderanch . Это было еще интереснее, потому что в нем участвовал JBoss.

Разработчики, знакомые с веб-приложениями Java EE, знают, что дескриптор развертывания веб-приложения (web.xml) позволяет указать «страницы ошибок», которые будут отображаться контейнером, когда сервер генерирует конкретное исключение (класс) или код ошибки для веб-запрос. Вот быстрый пример того, как это выглядит:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<web-app
   ... 
   <!-- A custom error page for error code == 500 --> 
   <error-page>  
     <error-code>500</error-code>  
     <location>/my-foo-bar-500-page.html</location>  
   </error-page>  
      
   <!-- A custom error page for exception type org.myapp.foo.bar.MyException --> 
   <error-page>  
     <exception-type>org.myapp.foo.bar.MyException</exception-type>  
     <location>/my-foo-bar-exception-page.html</location>  
   </error-page>  
   ... 
      
 </web-app>

Достаточно просто — пара пользовательских страниц ошибок, определенных для конкретного кода ошибки и типа исключения соответственно. Все это прекрасно работает. В настоящее время при разработке веб-приложений появляется все больше и больше моделей и структур программирования. CDI и JSF — некоторые из них. CDI имеет эту концепцию областей (например: область запроса, область сеанса, область приложения, область диалога). Мы не будем вдаваться в подробности того, что это такое и когда они используются, но давайте рассмотрим объем беседы в этом блоге, поскольку именно об этом шла речь в ветке форума, которая вызвала этот блог.

Таким образом, CDI позволяет нескольким запросам быть частью «области диалога». Разговор имеет «начало» и «конец», оба из которых могут управляться приложением. Когда приложение использует JSF, любой диалог (id) автоматически распространяется на запрос (ы) JSF. Помимо явного начала / конца разграничения разговоров, разговор также может быть прерван. Запрос, который относится к разговору, который закончился или истек тайм-аут, приведет к исключению.

Таким образом, мы знаем, что у нас есть немного предыстории для обсуждения CDI. Итак, давайте рассмотрим случай, когда приложение хочет представить красиво выглядящую страницу, когда возникает исключение «разговора больше нет» (возможно, из-за тайм-аута). Мы видели, как написать файл web.xml для конфигураций страниц с ошибками — это было бы так просто:

01
02
03
04
05
06
07
08
09
10
11
<web-app
   ... 
      
   <!-- A custom error page for exception type org.jboss.weld.context.NonexistentConversationException --> 
   <error-page>  
     <exception-type>org.jboss.weld.context.NonexistentConversationException</exception-type>  
     <location>/my-foo-bar-exception-page.html</location>  
   </error-page>  
   ... 
      
 </web-app>

Достаточно просто. Org.jboss.weld.context.NonexistentConversationException — это тип класса исключения, который генерируется по истечении времени ожидания диалога (обратите внимание, что мы предполагаем, что веб-приложение использует Weld в качестве библиотеки реализации спецификации CDI). Вышеуказанная конфигурация работает отлично. My-foo-bar-exception-page.html отображается, когда генерируется исключение org.jboss.weld.context.NonexistentConversationException. НО, давайте теперь рассмотрим, что мы хотим включить JSF на страницу ошибок, как и другие части нашего приложения. Итак, давайте укажем страницу ошибок на шаблон URL, который отображается на сервлет JSF:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<web-app
   ... 
      
   <!-- A custom error page for exception type org.jboss.weld.context.NonexistentConversationException. 
     Notice the "nocid" parameter being passed to make sure that the non-existent conversation id 
     isn't passed to the error page 
   --> 
   <error-page>  
     <exception-type>org.jboss.weld.context.NonexistentConversationException</exception-type>  
     <location>/my-foo-bar-exception-page.xhtml?nocid=true</location>  
   </error-page>  
   ... 
      
 </web-app>

Обратите внимание, что мы передаем параметр ‘nocid’ как часть строки запроса местоположения страницы ошибки. Значение параметра ‘nocid’ на самом деле не имеет значения, но для сохранения логического значения мы здесь использовали значение ‘true’. Как только это изменение будет сделано, вы начнете замечать, что страница с ошибкой (поддерживаемая JSF) теперь отображается правильно!

Нам потребовалось некоторое время, чтобы найти это решение в этой ветке форума, потому что оно выглядело настолько простым, что должно было «просто сработать », но не сработало. Вот ветка форума на coderanch, о которой я говорил. Автор благодарности Грегу Чарльзу за то, что он выяснил, как передать этот параметр nocid.

Ссылка: Пользовательские страницы ошибок для истекших разговоров с участием CDI и JSF от нашего партнера JCG Джейкирана Пая в блоге Jaikiran My Wiki .