Как программно зарегистрировать JSF ExceptionHandlerFactory в Spring Boot

Я использую Joinfaces для создания приложения JSF + Spring Boot, и Omnifaces упакован с ним.

Когда срок действия представления истекает, и я перемещаюсь, я получаю ViewExpiredException. Когда я запускаю Ajax, страница ничего не делает, и в консоли отображается ошибка.

Можно ли программно зарегистрировать org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory с помощью Spring, не добавляя в мой проект .xml (веб, Faces-config)?


person BBacon    schedule 09.11.2018    source источник


Ответы (1)


Используйте следующее, чтобы настроить собственный обработчик исключений без web.xml:

FactoryFinder.setFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY,"org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory");

Хитрость заключается в том, чтобы убедиться, что эта строка выполняется как можно раньше при запуске; как только среда выполнения JSF вызывает FactoryFinder.getFactory(), уже слишком поздно менять настроенный обработчик.

Хорошо то, что я на самом деле не могу найти нигде в кодовой базе Mojarra, где фабрика обработчиков исключений устанавливается по умолчанию, поэтому вы, вероятно, могли бы выполнить это, возможно, в конструкторе (не @PostConstructor) любого @ApplicationScoped bean. Вы также можете сделать это в статическом инициализаторе bean-компонента ame.

Кроме того, вы можете сделать это в файле FacesInitializer. Итак, предполагая, что вы используете Mojarra, вам нужно настроить обработчик очень рано в процессе запуска контекста сервлета.

public class YourWebAppInitializer extends FacesInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext ctxt) throws ServletException {

        AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
        root.register(YourSpringConfigClass.class);
        ctxt.addListener(new ContextLoaderListener(root));
        FactoryFinder.setFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY,"org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory");
    }
}

WebApplicationInitializer — это стандартный интерфейс, поддерживаемый Spring для начальной загрузки веб-приложения, и я предполагаю, что он у вас уже есть, потому что у вас нет web.xml — не стесняйтесь заменять содержимое метода onStartup тем, что у вас есть. в вашей фактической реализации. Ключевым моментом здесь является убедиться, что вы установили фабрику там, что довольно рано при запуске приложения.

Также обратите внимание, что вы можете вручную установить фактический ExceptionHandler для любого данного экземпляра FacesContext (хотя я не проверял это, чтобы увидеть, как он будет себя вести или будет ли он работать хорошо)

person kolossus    schedule 10.11.2018
comment
Мой аннотированный класс '@SpringBootApplication' расширяет SpringBootServletInitializer, я '@Override' его метод onStartup и включаю 'FactoryFinder.setFactory', как упоминалось вами (я вызываю super() внутри него, чтобы убедиться, что Spring Boot может делать свое дело), ​​но это не работает. Есть идеи, почему? - person BBacon; 13.11.2018
comment
Я попытался удалить SpringBootServletInitializer и просто расширить FacesInitializer, та же проблема, при вызовах Ajax ничего не происходит, и ошибка выводится на консоль. - person BBacon; 13.11.2018