Why my custom javax.faces.context.ExceptionHandler doesn't handle javax.validation.ConstraintViolationException

北战南征 提交于 2021-02-11 14:27:21

问题


My custom exception handler is not being invoked by the container to intercept (checked or unchecked) exceptions (I verified it through the debugger). I have this Entity bean class with @Email annotation for the email field, and when the user types in an invalid email through the JSF page, an error message is being displayed, however, the error message is not the one I set through the custom exception handler class, rather it is the one I have set as the default message for the @Email annotation. The error message generated by the custom exception handler has a prefix string "Exception caught by the custom Exception handler: ". I surmise that an invalid email should throw a ConstraintViolationException, which would be an ideal case for the exception handler to catch.

The JSF page allows the user information to be updated, so when I update the user's email with an invalid one and click the "Update" CommandButton, the registered action method is not being invoked (I verified it through the debugger). Furthermore, what I don't seem to figure out, is that when the "invalid email" error message is displayed on the JSF page, the "Add User" command Button gets disabled, so I can not navigate to the "Add User" JSF page. Any idea, why the exception handler and the page navigation (Add User) are not working in case of an error?

public class CustomExceptionHandler extends ExceptionHandlerWrapper {

    private ExceptionHandler wrapped;
    private final static Logger logger = Logger.getLogger(CustomExceptionHandler.class.getName());

    public CustomExceptionHandler(ExceptionHandler w) {
        wrapped = w;
    }

@Override
  public ExceptionHandler getWrapped() {
    return wrapped;
  }

  @Override
  public void handle() throws FacesException {
    Iterator iterator = getUnhandledExceptionQueuedEvents().iterator();
    
    while (iterator.hasNext()) {
      ExceptionQueuedEvent event = (ExceptionQueuedEvent) iterator.next();
      ExceptionQueuedEventContext context = (ExceptionQueuedEventContext)event.getSource();
 
      Throwable throwable = context.getException();
      
      FacesContext fc = FacesContext.getCurrentInstance();
      
      try {
          Flash flash = fc.getExternalContext().getFlash();
          
          // Put the exception in the flash scope to be displayed in the error 
          // page if necessary ...
          String errorMessage = "Exception caught by the custom Exception handler: "+throwable.getMessage();
          logger.severe(errorMessage);
          flash.put("errorDetails", errorMessage);
          
          
          NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();
          
          //navigationHandler.handleNavigation(fc, null, "/loginmanagement");
          navigationHandler.handleNavigation(fc, null, "error?faces-redirect=true");
          
          fc.renderResponse();
      } finally {
          iterator.remove();
      }
    }
    
    // Let the parent handle the rest
    getWrapped().handle();
  }
}

The factory class: public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory { private ExceptionHandlerFactory parent;

  public CustomExceptionHandlerFactory(ExceptionHandlerFactory parent) {
    this.parent = parent;
  }
 
  @Override
  public ExceptionHandler getExceptionHandler() {
    ExceptionHandler result = new CustomExceptionHandler(parent.getExceptionHandler());
    return result;
  }
}

The faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.3"
              xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd">

    <application>
        <resource-bundle>
            <base-name>webmessages</base-name>
            <var>bundle</var>
        </resource-bundle>
        <locale-config>
            <default-locale>en</default-locale>
            <!--      <supported-locale>es</supported-locale>   -->
        </locale-config>
    </application>
    <error-page>
        <exception-type>java.lang.RuntimeException</exception-type>
        <location>/loginmanagement.xhtml</location>
    </error-page> 
    <factory>
        <exception-handler-factory>
            org.me.mavenlistservicedb.applicationexception.CustomExceptionHandlerFactory
        </exception-handler-factory>
    </factory>
</faces-config>

Here is the relevant excerpt of the JSF page

<h:column>
                            <f:facet name="header">#{bundle.loginmanagementemail}</f:facet>
                            <h:inputText value = "#{l.email}"
                                         size ="30" rendered = "#{l.canUpdate}" />
                            <h:outputText value = "#{l.email}"
                                          rendered = "#{not l.canUpdate}" />
</h:column>
 <f:facet name="footer">
                        <h:panelGroup style="display: block; border-color: aquamarine;text-align: center;">

                            <h:commandButton id="update"
                                             value="Save updates"
                                             action="#{loginManagment.saveUpdate}" />
                            <h:commandButton id="add"
                                             value="Add User"
                                             action="adduser" />
                        </h:panelGroup>
</f:facet>

I use Netbeans on Windows 10 with Glassfish 5.1.

Thanks

来源:https://stackoverflow.com/questions/65632534/why-my-custom-javax-faces-context-exceptionhandler-doesnt-handle-javax-validati

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!