Java 为什么表单提交没有';不行?

Java 为什么表单提交没有';不行?,java,jsf,Java,Jsf,我有下一张表格: <h:form> <h:selectManyListbox value="#{reports.selectedCategories}" converter="#{categoryConverter}"> <f:selectItems value="#{reports.categories}"/> </h:selectManyListbox>

我有下一张表格:

<h:form>
    <h:selectManyListbox value="#{reports.selectedCategories}"
                         converter="#{categoryConverter}">
        <f:selectItems value="#{reports.categories}"/>
    </h:selectManyListbox>
    <h:commandButton value="Submit" action="#{reports.action}" />
</h:form>
最后是我的支持bean代码:

public class ReportsController {

    private Category[] selectedCategories;

    public void setSelectedCategories (Category[] categories) {
        System.out.println ("SET CATEGORIES");
        this.selectedCategories = categories;
    }

    public Category[] getSelectedCategories () {
        System.out.println ("GET CATEGORIES");
        return selectedCategories;
    }

    public void action () {
        System.err.println ("ACTION");
    }

    ....
    //methods for accessing data

}
当我启动我的应用程序时,我看到了正确的列表框,有2个项目和一个按钮“提交”。但当我按下submit时,什么也没发生。我看到的唯一输出是:

GET CATEGORIES
CONVERTER: GET AS STRING
CONVERTER: GET AS STRING
setSelectedCategories()和action()方法都不会被调用。我不明白为什么。有什么建议吗

UPD:问题甚至更愚蠢:当我注释了所有与Category类相关的东西(即我的selectManyListbox、我的转换器、所有相关的setter和getter)和只剩下方法操作时,它仍然没有被调用

<h:form>
    <h:commandButton value="Submit" action="#{reports.action}" />
</h:form>
看起来所有的阶段都很好,但事实并非如此。我有点困惑。

因为在“转换器”下,您应该按照faces-config.xml中的定义提供转换器名称:

<converter>
    <converter-id>myConverter</converter-id>
    <converter-class>com.example.converters.MyConverter</converter-class>
</converter>

myConverter
com.example.converter.MyConverter
在这种情况下,在表单中加入
通常是有帮助的,因为您可以看到哪里出了问题。

当JSF表单“不工作”时,这通常表示某些东西(通常是组件、验证器或转换器)已指示生命周期某些输入无效,应停止处理并重新渲染视图。这可以防止垃圾数据进入模型,并阻止业务逻辑对无效输入执行操作

这将在某种程度上取决于视图的配置以及插入其中的任何代码的逻辑。同样,在视图中添加
标记通常会通知您哪些组件触发了此响应。在调试期间,配置通常很有用,可以告诉您在请求期间完成了哪些阶段


此方法应返回一个
字符串

public String action () {
    System.err.println ("ACTION");
    return null;
}
某些实现允许使用
void
返回类型,但它违反了规范。
action
属性必须绑定到以下中定义的应用程序操作:

应用程序操作

  • 方法必须是公共的
  • 该方法不能采用任何参数
  • 该方法必须返回对象
操作方法将由调用 默认的ActionListener 实现,如中所述 第7.1.1节“ActionListener 上述“财产”。它的责任是 执行所需的应用程序 操作,然后返回一个逻辑 “结果”(表示为字符串) 可以由一个 导航处理程序,以便 确定应该使用哪个视图 下一个


当JSF表单提交失败时,您需要确保:

  • ui命令
    组件必须嵌套在
    ui表单
    组件中

    <h:form>
        <h:commandButton value="submit" action="#{bean.submit}" />
    </h:form>
    
  • 不应发生任何验证/转换错误(使用
    h:messages
    获取所有消息)

    
    
  • 如果
    UICommand
    组件嵌套在
    UIData
    组件中(例如
    h:dataTable
    ),请确保保留完全相同的数据模型(值
    属性后面的对象)。测试这一点的最简单方法是将bean放在会话范围内。如果这解决了问题,那么您需要检查数据加载逻辑

  • 组件和所有父组件的
    呈现属性
    禁用属性不应进行负面评估。测试这一点的最简单方法是将bean放在会话范围内。如果这解决了问题,那么您需要检查负责此问题的代码

  • 确保没有任何
    PhaseListener
    或任何
    EventListener
    更改请求生命周期以跳过调用操作阶段

  • 确保同一请求链中没有
    过滤器
    /
    Servlet
    以某种方式阻止了
    FacesServlet
    的请求


  • 至于你的实际问题;您没有获得
    PropertyNotFoundException
    s或类似信息,并且您的
    PhaseListener
    已经很好地执行了所有适当的生命周期阶段,因此我认为您的问题实际上是由2引起的。嵌套表单

    但实际上找到了我的转换器,并且成功调用了它的getAsString方法。@Roman-您是否尝试根据我的编辑更改
    操作
    方法签名?是的,我尝试返回空字符串,最后返回导航规则中映射的字符串“action”,结果没有更改((这不是我的项目,它已经包含了一些spring安全性的东西,可能问题就在那里,我不知道。如果我从头开始开发项目,这里的所有代码都会按预期工作。我在稍早的时候发现了问题,然后你的答案出现了,但我的问题在你的2项中描述。项目中有一个模板添加了form-wrapper访问每个页面。不过(幸运的是)这两个impl在这方面都是宽容的。
    void
    操作也是允许的,如果您想避免url屏蔽/backbutton/SEO/等问题带来的所有麻烦,这是理想的。只需让表单提交给self并有条件地显示结果,然后使用
    GET
    (输出链接)仅用于普通导航。@BalusC-ah,我最近没有测试过这个;如果内存可用,这通常会导致错误。
    public void action () {
        System.err.println ("ACTION");
    }
    
    public String action () {
        System.err.println ("ACTION");
        return null;
    }
    
    <h:form>
        <h:commandButton value="submit" action="#{bean.submit}" />
    </h:form>
    
    <h:form>
        <h:form>
            <h:commandButton value="this will not work" action="#{bean.fail}" />
        </h:form>
    </h:form>
    
    <h:form>
        <h:commandButton value="submit" action="#{bean.submit}" />
        <h:messages />
    </h:form>