Scope in JSF Validator

I want to implement input validation. This is the managed bean code:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"    
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head>
        <ui:insert name="header">           
            <ui:include src="header.xhtml"/>         
        </ui:insert>
    </h:head>
    <h:body>

        <h1><img src="resources/css/images/icon.png" alt="NVIDIA.com" /> History Center</h1>
        <!-- layer for black background of the buttons -->
        <div id="toolbar" style="margin: 0 auto; width:1180px; height:30px; position:relative;  background-color:black">
            <!-- Include page Navigation -->
            <ui:insert name="Navigation">           
                <ui:include src="Navigation.xhtml"/>         
            </ui:insert>

        </div>  

        <div id="logodiv" style="position:relative; top:35px; left:0px;"> 
            <h:graphicImage alt="Demo Insert Form"  style="position:relative; top:-20px; left:9px;"  value="resources/images/logo_databasez.png" />
        </div>
        <div id="main" style="margin: 0 auto; width:1190px; height:700px; position:absolute;  background-color:transparent; top:105px">

            <div id="mainpage" style="margin: 0 auto; width:1190px; height:500px; position:absolute;  background-color:transparent; top:80px">

                <div id="settingsHashMap" style="width:350px; height:400px; position:absolute;  background-color:r; top:20px; left:1px">
                    <h:form>
                        <div id="settingsdiv" style="width:750px; height:400px; position:absolute;  background-color:r; top:20px; left:1px">

                            <h:panelGrid columns="2">
                                <h:panelGroup>Session ID</h:panelGroup>
                                <h:panelGroup>
                                    <h:inputText id="sessionid" value="#{DatabaseController.formMap['sessionid']}" >
                                        <f:validateLength minimum="0" maximum="15"/>
                                        <f:validator binding="#{ValidatorController.validateMessage}" >
                                            <f:attribute name="type" value="sessionid" />
                                        </f:validator>
                                        <f:ajax event="blur" render="sessionidvalidate" />                                          
                                    </h:inputText>
                                    <h:message id="sessionidMessage" for="sessionid" />
                                </h:panelGroup>

                                <h:panelGroup>User ID</h:panelGroup>
                                <h:panelGroup>
                                    <h:inputText id="userid" value="#{DatabaseController.formMap['userid']}" >
                                        <f:validateLength minimum="0" maximum="15"/>
                                    </h:inputText>
                                </h:panelGroup>

                                <h:panelGroup>Login Time</h:panelGroup>
                                <h:panelGroup>
                                    <h:inputText id="logintime" value="#{DatabaseController.formMap['logintime']}" >
                                        <f:validateLength minimum="0" maximum="35"/>
                                    </h:inputText>
                                </h:panelGroup>

                                <h:panelGroup>Last Refresh Time</h:panelGroup>
                                <h:panelGroup>
                                    <h:inputText id="lastrefreshtime" value="#{DatabaseController.formMap['lastrefreshtime']}" >
                                        <f:validateLength minimum="0" maximum="35"/>
                                    </h:inputText>
                                </h:panelGroup>

                                <h:panelGroup>User IP</h:panelGroup>
                                <h:panelGroup>
                                    <h:inputText id="userip" value="#{DatabaseController.formMap['userip']}" >
                                        <f:validateLength minimum="0" maximum="15"/>
                                    </h:inputText>
                                </h:panelGroup>

                            </h:panelGrid>          

                        </div>   

                        <div id="settingstwodiv" style="width:150px; height:60px; position:absolute;  background-color:transparent; top:380px; left:800px">

                            <h:commandButton value="Create User" action="#{DatabaseController.saveData}"/>

                        </div> 
                    </h:form> 

                </div>   

            </div>  
        </div>

    </h:body>
</html>

This is the code I added in faces-config.xml

<validator>
    <validator-id>ValidatorController</validator-id>
    <validator-class>com.DX_57.HM_57.FormValidator</validator-class>
</validator>

This is the verification code I tried to verify:

import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.inject.Named;

@Named("ValidatorController")
@SessionScoped
public class FormValidator implements Validator {

    public FormValidator() {
    }

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void validateMessage(FacesContext context, UIComponent component, Object value) throws ValidatorException {

        if (value.equals("test")) {
            throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "Session ID is already in use, please choose another.", null));
        }
    }
}

The problem is this error that I get when I try to run the example:

[#|2012-05-05T22:39:00.096+0300|INFO|glassfish3.1.2|org.glassfish.osgiweb|_ThreadID=58;_ThreadName=Thread-2;|Removed bundle 710 against context path /test |#]

[#|2012-05-05T22:39:00.097+0300|WARNING|glassfish3.1.2|org.glassfish.osgijavaeebase|_ThreadID=58;_ThreadName=Thread-2;|Failed to deploy bundle com.DX_57.History-Module-57 [710]
org.glassfish.osgijavaeebase.DeploymentException: Deployment of com.DX_57.History-Module-57 [710] failed because of following reason: Failed while deploying bundle com.DX_57.History-Module-57 [710] : java.lang.RuntimeException: Failed to deploy bundle [ com.DX_57.History-Module-57 [710] ], root cause: Exception while loading the app
    at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.deploy(AbstractOSGiDeployer.java:125)
    at org.glassfish.osgijavaeebase.OSGiContainer.deploy(OSGiContainer.java:154)
    at org.glassfish.osgijavaeebase.JavaEEExtender.deploy(JavaEEExtender.java:107)
    at org.glassfish.osgijavaeebase.JavaEEExtender.access$200(JavaEEExtender.java:61)
    at org.glassfish.osgijavaeebase.JavaEEExtender$HybridBundleTrackerCustomizer$1.call(JavaEEExtender.java:151)
    at org.glassfish.osgijavaeebase.JavaEEExtender$HybridBundleTrackerCustomizer$1.call(JavaEEExtender.java:148)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.RuntimeException: Failed to deploy bundle [ com.DX_57.History-Module-57 [710] ], root cause: Exception while loading the app
    at org.glassfish.osgijavaeebase.OSGiDeploymentRequest.deploy(OSGiDeploymentRequest.java:196)
    at org.glassfish.osgijavaeebase.OSGiDeploymentRequest.execute(OSGiDeploymentRequest.java:118)
    at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.deploy(AbstractOSGiDeployer.java:121)
    ... 10 more
Caused by: org.glassfish.deployment.common.DeploymentException: WELD-000072 Managed bean declaring a passivating scope must be passivation capable.  Bean:  Managed Bean [class com.DX_57.HM_57.FormValidator] with qualifiers [@Any @Default @Named]
    at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:181)
    at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:128)
    at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:277)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:460)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
    at org.glassfish.osgijavaeebase.OSGiDeploymentRequest.deploy(OSGiDeploymentRequest.java:183)
    ... 12 more
Caused by: org.jboss.weld.exceptions.DefinitionException: WELD-000072 Managed bean declaring a passivating scope must be passivation capable.  Bean:  Managed Bean [class com.DX_57.HM_57.FormValidator] with qualifiers [@Any @Default @Named]
    at org.jboss.weld.bean.ManagedBean.checkType(ManagedBean.java:405)
    at org.jboss.weld.bean.AbstractBean.initializeAfterBeanDiscovery(AbstractBean.java:149)
    at org.jboss.weld.bean.AbstractClassBean.initializeAfterBeanDiscovery(AbstractClassBean.java:308)
    at org.jboss.weld.bean.ManagedBean.initializeAfterBeanDiscovery(ManagedBean.java:361)
    at org.jboss.weld.bootstrap.BeanDeployment.doAfterBeanDiscovery(BeanDeployment.java:216)
    at org.jboss.weld.bootstrap.BeanDeployment.afterBeanDiscovery(BeanDeployment.java:208)
    at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:352)
    at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:179)
    ... 17 more
|#]

It seems that the Validator class is not in the right area. What area should I use?

Best regards

+5
source share
2 answers

Check this code:

<h:panelGroup>Session ID</h:panelGroup>
<h:panelGroup>
    <h:inputText id="sessionid" value="#{DatabaseController.formMap['sessionid']}" 
                    validator="#{ValidatorController.validatebean}">                                        
        <f:ajax event="blur" render="sessionidMessage" />                                          
    </h:inputText>
    <h:message id="sessionidMessage" for="sessionid" />
</h:panelGroup>

This is a bean:

@Named("ValidatorController")
@ViewScoped
public class FormValidator implements Validator {

    public FormValidator() {
    }

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        if (value.equals("test")) {
            throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "  Session ID is already in use, please choose another.", null));
        }
    }

    public void validatebean(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        if (value.equals("test")) {
            throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "  Session ID is already in use, please choose another.", null));
        }
    }

}
+1
source

In the WELD documentation:

Managed beans with an @SessionScoped or @ConversationScoped scope must be serializable, as the container passivates an HTTP session from time to time.

There may be other reasons, but your CDI bean session should at least implement an interface Serializable:

@Named("ValidatorController")
@SessionScoped
public class FormValidator implements Validator, Serializable {
...
}
+10
source

All Articles