【问题标题】:Scope in JSF ValidatorJSF 验证器中的作用域
【发布时间】:2012-05-14 23:39:24
【问题描述】:

我想实现输入字段验证。这是托管 bean 的代码:

<?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>

这是我添加到 faces-config.xml 中的代码

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

这是我尝试测试的验证器的代码:

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));
        }
    }
}

问题是我在尝试运行示例时遇到此错误:

[#|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
|#]

Validator 类似乎不在正确的范围内。我必须使用什么范围?

最好的祝福

【问题讨论】:

  • Matt 已经回答了您当前的问题,但您在验证器中也存在其他重大错误。修复您的验证器以完全匹配我对您上一个问题的回答中的示例。您应该在Validator 接口的validate() 方法中完成这项工作,而不是自定义方法。您不应该需要 faces-config.xml 中的旧 JSF 1.x &lt;validator&gt; 声明。您应该引用 binding 中的具体验证器实例,而不仅仅是它的方法。
  • 好的,但是如果我删除 faces-config.xml 中的声明,我可以在验证器中使用 CDI 吗?我想实现自定义验证器,因为如果我有 20 个输入字段,我必须在不同的 Java 类和文件中实现 20 个标准验证器。我想在一个文件中完成。
  • 试试看?您的 faces 配置声明不会以任何方式使用。它仅用于validatorId
  • 我从 faces-config.xml 中删除了验证器的声明。我以这种方式编辑了代码:pastebin.com/a3GE3EL5 但是当我测试它时没有任何反应。
  • 如果您想实现例如 20 个验证器,您将如何实现代码以简化代码并减少 java 类的数量?

标签: java jsf jsf-2


【解决方案1】:

来自 WELD 文档:

范围为 @SessionScoped 或 @ConversationScoped 的托管 bean 必须是 可序列化,因为容器从 时不时的。

可能还有其他原因,但您的 CDI 会话范围 bean 至少应该实现 Serializable 接口:

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

【讨论】:

    【解决方案2】:

    测试这段代码:

    <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>
    

    这是豆子:

    @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));
            }
        }
    
    }
    

    【讨论】:

    • 哇,我不知道为什么以及如何工作,但是这段代码可以工作!谢谢大家!
    猜你喜欢
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 2013-07-25
    • 2015-09-01
    • 2014-05-29
    • 2013-11-25
    • 2011-04-28
    • 2018-01-28
    相关资源
    最近更新 更多