java.lang.IllegalArgumentException:发布管理

时间:2013-12-13 22:58:43

标签: jsf-2 jstl

我的xhtml页面:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"   
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jstl/core"
      >
    <h:head>
        <!-- <h:outputStylesheet library="css" name="table-style.css"  /> -->
    </h:head>

    <h:body>

        <h1>category</h1>
        <h:form id="form">
            <h:panelGrid columns="1">
                <c:forEach items="#{categoryBean.parentCategoryList}" var="cat">
                    <h:panelGroup>
                        <h:outputText value="#{cat.name}"/>
                        <h:commandButton value="+" type="button" onclick="expand('#{cat.name}');"/>
                    </h:panelGroup>
                    <h:panelGroup>
                        <h:selectManyCheckbox id="#{cat.name}" style="display: none" value="#{categoryBean.selectedCategoryList}">
                            <f:selectItems value="#{categoryBean.getSubCategoryList(cat.id)}" var="sub" itemLabel="#{sub.name}" itemValue="#{sub.name}"/>
                        </h:selectManyCheckbox>
                    </h:panelGroup>
                </c:forEach>
            </h:panelGrid>
            <h:commandButton value="Submit" action="result" />
            <h:commandButton value="Reset" type="reset" />
        </h:form>

        <script type="text/javascript">
            function expand(cat) {
                var name = "form:" + cat;
                alert(name);
                var element = document.getElementById(name);
                if(element.style.display == 'block') {
                  element.value = "-";
                  element.style.display = 'none';
                } else {
                  element.value = "+";
                  element.style.display = 'block'
                }
            }
        </script>   
    </h:body>
</html>

我的托管bean

package com.gtp.iqp.presentation.managedBeans;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.gtp.iqp.business.bo.Category;
import com.gtp.iqp.business.delegate.CategoryDelegate;

@SuppressWarnings("serial")
@Component
public class CategoryBean extends BaseManagedBean {

    @Autowired
    private CategoryDelegate categoryDelegate;
    private List<Category>   parentCategoryList;
    private List<String>     selectedCategoryList;

    public CategoryDelegate getCategoryDelegate() {
        return categoryDelegate;
    }
    public void setCategoryDelegate(CategoryDelegate categoryDelegate) {
        this.categoryDelegate = categoryDelegate;
    }
    public List<Category> getParentCategoryList() {
        parentCategoryList = categoryDelegate.getParentCategories();
        return parentCategoryList;
    }
    public void setParentCategoryList(List<Category> parentCategoryList) {
        this.parentCategoryList = parentCategoryList;
    }
    public List<String> getSelectedCategoryList() {
        return selectedCategoryList;
    }
    public void setSelectedCategoryList(List<String> selectedCategoryList) {
        this.selectedCategoryList = selectedCategoryList;
    }
    public List<Category> getSubCategoryList(long parent) {
        return categoryDelegate.getSubCategories(parent);
    }

}

我的问题

<f:selectItems value="#{categoryBean.getSubCategoryList(cat.id)}"/>

上面的selectItems语句能够从数据库中获取列表。我能够看到托管bean包含列表。但是,一旦控件转移到xhtml页面,它就不会显示出来。我看到以下异常:

Hibernate: select this_.id as id1_1_0_, this_.name as name2_1_0_, this_.parent as parent3_1_0_ from category this_ where this_.parent=?
Hibernate: select this_.id as id1_1_0_, this_.name as name2_1_0_, this_.parent as parent3_1_0_ from category this_ where this_.parent=?
Hibernate: select this_.id as id1_1_0_, this_.name as name2_1_0_, this_.parent as parent3_1_0_ from category this_ where this_.parent=?
Dec 13, 2013 2:56:06 PM com.sun.faces.context.ExceptionHandlerImpl log
FATAL: JSF1073: java.lang.IllegalArgumentException caught during processing of RENDER_RESPONSE 6 : UIComponent-ClientId=, Message=Release Management
Dec 13, 2013 2:56:06 PM com.sun.faces.context.ExceptionHandlerImpl log
FATAL: Release Management
java.lang.IllegalArgumentException: Release Management
    at javax.faces.component.UIComponentBase.validateId(UIComponentBase.java:592)
    at javax.faces.component.UIComponentBase.setId(UIComponentBase.java:412)
    at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.assignUniqueId(ComponentTagHandlerDelegateImpl.java:373)
    at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:176)
    at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
    at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
    at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:190)
    at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
    at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
    at com.sun.faces.facelets.tag.jstl.core.ForEachHandler.apply(ForEachHandler.java:230)
    at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
    at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:190)
    at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
    at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
    at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
    at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:190)
    at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
    at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
    at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
    at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:190)
    at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
    at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
    at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
    at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
    at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:161)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:980)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:99)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

有人可以告诉我我做错了什么,我该如何解决?

1 个答案:

答案 0 :(得分:3)

仔细查看堆栈跟踪顶行中的类/方法名称,一个好的库具有相当自我解释的类/方法名称:

java.lang.IllegalArgumentException: Release Management
    at javax.faces.component.UIComponentBase.validateId(UIComponentBase.java:592)
    at javax.faces.component.UIComponentBase.setId(UIComponentBase.java:412)

因此,它在设置UI组件的id期间发生。该ID正在验证且不被视为有效。实际上,根据javadoc

Release Management内部空格无效
  

设置此UIComponent的组件标识符(如果有)。组件标识符必须遵守以下语法限制:

     
      
  • 不得为零长度字符串。
  •   
  • 第一个字符必须是字母或下划线(&#39; _&#39;)。
  •   
  • 后续字符必须是字母,数字,下划线(&#39; _&#39;)或短划线(&#39; - &#39;)。
  •   

根据HTML spec,HTML元素ID中的空格也是无效的(你知道,JSF基本上只是一个HTML代码生成器,它当然应该尊重HTML规范):

  

ID和NAME令牌必须以字母([A-Za-z])开头,后面可以跟任意数量的字母,数字([0-9]),连字符(&#34; - &#34 ;),下划线(&#34; _&#34;),冒号(&#34;:&#34;)和句号(&#34;。&#34;)。

罪魁祸首在这里:

<h:selectManyCheckbox id="#{cat.name}" ...>

在这种特殊情况下,您基本上有2个选项可以解决它:

  1. 使用<h:dataTable>代替<h:panelGrid><c:forEach>,它会收到以行索引为前缀的自动生成ID:

    <h:dataTable value="#{categoryBean.parentCategoryList}" var="cat">
        <h:column>
            <h:outputText value="#{cat.name}"/>
            <h:commandButton value="+" type="button" onclick="expand('#{cat.name}');"/>
            <br/>
            <h:selectManyCheckbox id="name" style="display: none" value="#{categoryBean.selectedCategoryList}">
                <f:selectItems value="#{categoryBean.getSubCategoryList(cat.id)}" var="sub" itemLabel="#{sub.name}" itemValue="#{sub.name}"/>
            </h:selectManyCheckbox>
        </h:column>
    </h:dataTable>
    
  2. 使用带<c:forEach varStatus>的增量数字后缀的固定前缀:

    <h:panelGrid columns="1">
        <c:forEach items="#{categoryBean.parentCategoryList}" var="cat" varStatus="loop">
            <h:panelGroup>
                <h:outputText value="#{cat.name}"/>
                <h:commandButton value="+" type="button" onclick="expand('#{cat.name}');"/>
            </h:panelGroup>
            <h:panelGroup>
                <h:selectManyCheckbox id="name_#{loop.index}" style="display: none" value="#{categoryBean.selectedCategoryList}">
                    <f:selectItems value="#{categoryBean.getSubCategoryList(cat.id)}" var="sub" itemLabel="#{sub.name}" itemValue="#{sub.name}"/>
                </h:selectManyCheckbox>
            </h:panelGroup>
        </c:forEach>
    </h:panelGrid>
    
  3. 如果有必要,不要忘记相应地更改expand() JS函数的参数。

相关问题