1

We're developing a web application with embedded tomcat, spring-boot (no mvc) and joinfaces. We don't have a web.xml nor a web-fragment.xml, so error page mapping is a bit difficult. We implemented error mapping as a @Bean annotated method in a @Configuration class. E.g.:

@Bean
    public ErrorPageRegistrar errorPageRegistrar() {
        return new ErrorPageRegistrar() {
            @Override
            public void registerErrorPages(ErrorPageRegistry registry) {
                registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, errorPage));
                registry.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, errorPage));
            }
        };
    }

Where errorPage is a static variable that points to the error file. Classes like FacesExceptionFilter or FullAjaxExceptionHandler from Omnifaces unfortunately do not work (since we do not have a web.xml). So is this approach really the best way to implement error page mapping in joinfaces or is there a better solution available?

dos_7
  • 21
  • 4

2 Answers2

2

I was able to configure error handing for primefaces using joinfaces and spring-boot 2. Ir order for it to work I extended the PrimeExceptionHandlerFactory to override the method that decides where the error page is according to the thrown exception. This extended error handler is configured on src/main/resources/META-INF/faces-config.xml. This approach also enabled the "p:ajaxExceptionHandler" component functionalities.

In my case, any web.xml configuration was ignored, I think that's because I use the embedded tomcat that provides spring boot. If you are deploying a read .war/.ear application you could just define the error page in the web.xml

This is quite a hack, is would be great if joinfaces could configure this when primefaces is detected, error handling is required in order to create a JSF aplication with primefaces.

Complete working project can be found at: https://github.com/ollbap/my-primefaces-spring-boot-skeleton

See:

faces-config.xml

<?xml version="1.0" encoding="windows-1252"?>
<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 2.2//EN"
  "http://java.sun.com/dtd/web-facesconfig_2_2.dtd">
<faces-config xmlns="http://java.sun.com/JSF/Configuration">
    <name>MyApplication</name>

    <ordering>
        <before>
            <others />
        </before>
    </ordering>

    <application>
        <el-resolver>org.primefaces.application.exceptionhandler.PrimeExceptionHandlerELResolver</el-resolver>
    </application>
    <factory>
        <exception-handler-factory>es.test.config.ExtendedPrimeExceptionHandlerFactory</exception-handler-factory>
    </factory>
</faces-config>

ExtendedPrimeExceptionHandlerFactory.java

package es.test.config;

import java.util.Map;

import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerFactory;

import org.eclipse.jdt.annotation.Nullable;
import org.primefaces.application.exceptionhandler.PrimeExceptionHandler;
import org.primefaces.application.exceptionhandler.PrimeExceptionHandlerFactory;

/**
 * Extended primefaces exception handler factory in order to create a exception
 * handler that redirects to the desired error page.
 */
public class ExtendedPrimeExceptionHandlerFactory extends PrimeExceptionHandlerFactory {
    private static final String ERROR_PAGE = "error.xhtml";

    public ExtendedPrimeExceptionHandlerFactory(final ExceptionHandlerFactory wrapped) {
        super(wrapped);
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        return new ExtendedPrimeExceptionHandler(getWrapped().getExceptionHandler());
    }

    private static class ExtendedPrimeExceptionHandler extends PrimeExceptionHandler {

        public ExtendedPrimeExceptionHandler(ExceptionHandler wrapped) {
            super(wrapped);
        }

        @Override
        protected String evaluateErrorPage(@SuppressWarnings("null") Map<String, String> errorPages,
                @Nullable Throwable rootCause) {
            return ERROR_PAGE;
        }

    }

}
ollbap
  • 96
  • 5
0

I found this solution for error handle and make it also same as URL resources

A way to solve this is to extend the WebMvcConfigurerAdapter. Yet, as of Spring 5, the WebMvcConfigurerAdapter is deprecated. A solution for this is to use the WebMvcConfigurer interface directly.

Create a WelcomePageRedirect class that implements WebMvcConfigurer.

so I made for example root for index and hello and error

Hope Fully be useful for you

OLD WAY

    import javax.faces.application.ResourceHandler;
    import javax.inject.Inject;

    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.Ordered;
    import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

    @Configuration
    public class DefaultView extends WebMvcConfigurerAdapter {

        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/").setViewName("forward:/index.xhtml");
            registry.addViewController("/hello") .setViewName("forward:/pages/hello.xhtml");

            registry.addViewController("

/error") .setViewName("forward:/jsf-templates/error_not_found.xhtml");

        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);

        super.addViewControllers(registry);
    }


}

new way

@Configuration
public class WelcomePageRedirect implements WebMvcConfigurer {

  @Override
  public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/")
        .setViewName("forward:/helloworld.xhtml");
    registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
  }
}

For more information https://codenotfound.com/jsf-primefaces-welcome-page-redirect-example.html

Ismail
  • 1,668
  • 1
  • 15
  • 10