【问题标题】:Certain method is not called by a view视图不调用某些方法
【发布时间】:2015-02-24 20:55:35
【问题描述】:

我在使用 JSF 时遇到了一个非常奇怪的问题,但我无法自己解决,因为我无法通过 Google 搜索到错误消息。问题是,我有一个提交新文章或更新现有文章的视图。

getArticle() 方法返回 - 如果 ?id=x 通过 url 设置 - id 为 x 的文章 POJO。否则纯属空新文章。根据 id 设置,模式 editArticle 设置为 true 或 false。

因此,如果我通过 URL 传递一个 id,表单将更改为“更新文章”并显示文章的值。但是如果我点击提交按钮,什么都不会发生。没有输出,没有错误。在 Firefox 中使用 HTTP Live Headers,我看到了对服务器的请求。在环回接口上用wireshark看,也有流量。

但另一方面,“创建新文章”-按钮(如果没有设置id)没有问题。

环境:JSF 2.2、Apache Tomcat 7/8、Java 7/8、Windows/Ubuntu(尝试了不同的环境,但总是相同,所以这似乎是“设计使然”的问题 :-))。还尝试重命名方法,通过 ActionListener 调用,更改 panelGrids 的顺序......但没有办法。 bean 的 updateArticle() 方法永远不会通过点击按钮来调用。

<h:form id="idMasterForm" enctype="multipart/form-data">
    <h:panelGroup rendered="#{userController.loggedIn}">
            <h:panelGrid columns="2" cellpadding="5">
                <p:outputLabel for="title" value="Title" />
                <p:inputMask id="title"
                    value="#{editArticleController.article.title}" />
                <p:outputLabel for="author" value="Author" />
                <p:inputText id="author" value="#{userController.id}"
                    readonly="true" />
                <p:outputLabel for="date" value="Date" />
                <p:inputMask id="date"
                    value="#{editArticleController.article.date}" readonly="true" />
                <p:outputLabel for="link" value="File" />
                <p:selectOneMenu id="link"
                    value="#{editArticleController.article.link}">
                    <f:selectItems value="#{uploadFilesController.filesItems}" />
                </p:selectOneMenu>
                <p:outputLabel for="editor" value="" />
                <p:editor id="editor" widgetVar="editorWidget"
                    value="#{editArticleController.article.text}" width="600" />
            </h:panelGrid>

            <h:panelGrid columns="2" style="margin-top: 10px" rendered="#{!editArticleController.editArticle}">
                <p:commandButton value="Submit new article"
                    action="#{editArticleController.createArticle()}"
                    icon="ui-icon-disk" />
                <p:commandButton value="Clear" type="button"
                    onclick="PF('editorWidget').clear();" icon="ui-icon-close" />
            </h:panelGrid>

            <h:panelGrid columns="2" style="margin-top: 10px" rendered="#{editArticleController.editArticle}" >
                <p:commandButton value="Update article"
                    action="#{editArticleController.updateArticle()}"
                    icon="ui-icon-disk" />
                <p:commandButton value="Clear" type="button"
                    onclick="PF('editorWidget').clear();" icon="ui-icon-close" />
            </h:panelGrid>
            <h:outputText rendered="#{ ! userController.loggedIn}"
                value="#{res.globNotLoggedIn}" />
    </h:panelGroup>
</h:form>

这里是托管 Bean:

import java.util.Date;

import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

import hwr.Util;
import hwr.g2.model.Archive;
import hwr.g2.model.Article;
import hwr.g2.model.Author;
import hwr.user.UserController;

@ManagedBean
public class EditArticleController {
    private Article article;
    private Boolean editArticle;
    private Integer editArticleID;

    public EditArticleController() {
        this.article = new Article();
        System.out.println("EditArticleController was called");
    }

    public Article getArticle() {
        //System.out.println("getArticle() was called");
        if (this.getEditArticle()) {
            this.article = new Article(this.editArticleID);
        }
        return this.article;
    }

    public void setArticle(Integer articleID) {
        this.article = new Article(articleID);
    }

    public void setArticle(Article article) {
        System.out.println("setArticle(Article article) was called");
        this.article = article;
    }

    public void setText(String text) {
        this.article.setText(text);
    }

    public String getText() {
        return this.article.getText();
    }

    public void setTitle(String title) {
        this.article.setTitle(title);
    }

    public String getTitle() {
        return this.article.getTitle();
    }

    public Boolean getEditArticle() {
        // https://stackoverflow.com/questions/550448/get-request-and-session-parameters-and-attributes-from-jsf-pages

        HttpServletRequest req = (HttpServletRequest) FacesContext
                .getCurrentInstance().getExternalContext().getRequest();
        try {
            this.editArticleID = Integer.valueOf(req.getParameter("id"));
            if (this.editArticleID > 0) {
                this.setEditArticle(true);
            } else {
                this.setEditArticle(false);
            }
        } catch (Exception e) {
            this.setEditArticle(false);
        }
        return editArticle;
    }

    public void setEditArticle(Boolean editArticle) {
        this.editArticle = editArticle;
    }

    public Date getActualDate() {
        Date d = new Date();
        return d;
    }

    public void rangChanged() {
        // nothing
    }

    public String createArticle() {
        System.out.println("New Article...");
        Util util = new Util();
        UserController user = (UserController) util.getBean("userController");

        this.article.setAuthor(new Author(user.getId()));
        this.article.setDate(new Date());

        try {
            Archive archive = new Archive();
            archive.addArticle(this.article);
        } catch (Exception e) {
            System.out.println("something goes wrong here...");
            e.printStackTrace();
        }
        return "g2_home?faces-redirect=true";
    }

    public String updateArticle() {
        System.out.println("*** Update Article... ***");

        System.out.println("Debug: Update article, ID "
                + this.article.getId() + "! title: " + this.article.getTitle()
                + " and text: " + this.article.getText()
                + " and written by "
                + this.article.getAuthor().getFirst());

        try {
            Archive archive = new Archive();
            archive.updateArticle(this.article);
        } catch (Exception e) {
            System.out.println("something goes wrong here...");
            e.printStackTrace();
        }
        return "g2_home?faces-redirect=true";

    }
}

我使用了 BalusC (action method is not called in JSF) 的清单,但没有找到任何东西。 如果有人能指出我正确的方向,那就太好了。顺便问一下,有没有更好的方法来填写表格?以我的方式,getArticle() 方法被视图多次调用。

【问题讨论】:

  • 感谢@BalusC!我删除了这两个按钮,并将它们替换为没有“渲染”的“保存文章”按钮。被调用的函数根据 editArticle 的状态调用 createArticle() 或 updateArticle()。结论是这样的:永远不要在表单中渲染操作按钮并保持 getter 非常简单?

标签: jsf jsf-2 primefaces


【解决方案1】:

我认为您应该定义托管 bean 范围 @ViewScoped 或您想要的任何其他范围。 看这个问题【问题】:What is the default Managed Bean Scope in a JSF 2 application?

【讨论】:

  • 嗨,感谢@Ahmed 的回复。我试过了,但没什么区别。甚至浏览器选项卡的加载器微调器也没有出现......浏览器中没有任何反应。在控制台中,我看到使用更新的标题调用了 Article 类的 setTitle(),并且还调用了 UploadFilesController,但不是 updateArticle() 的调试输出。
【解决方案2】:

如果不设置 bean 的范围,则默认为@RequestScoped,这意味着将根据用户请求重新创建 bean。将其更改为 @ViewScoped 至少是为了让 bean 在用户与多个请求(例如 ajax 请求)中的同一视图交互时保持活动状态。

@ManagedBean
@ViewScoped
public class EditArticleController {
    //rest of class definition
}

【讨论】:

  • 您好,也感谢您的回复。正如我在一分钟前写的那样:我试过了,但没有任何区别。甚至浏览器选项卡的加载器微调器也没有出现......浏览器中没有任何反应。在控制台中,我看到使用更新的标题调用了 Article 类的 setTitle(),并且还调用了 UploadFilesController,但不是 updateArticle() 的调试输出。
猜你喜欢
  • 2011-06-19
  • 2020-08-03
  • 1970-01-01
  • 2019-01-23
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多