2014-12-28 41 views
0

我对JSF有一个非常奇怪的问题,但是我无法自行解决它,因为我没有任何错误消息可供Google使用。问题是,我有一种观点来提交新文章或更新现有文章。某些方法不被视图调用

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

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

但另一方面,“创建新文章” - 巴顿(如果id没有设置)没有问题。 )(环境:JSF 2.2,Apache Tomcat 7/8,Java 7/8,Windows/Ubuntu(尝试不同的envs,但总是相同的,所以它似乎是一个“设计”问题:-))。也尝试重命名方法,通过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> 

这里是Managed 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()方法被视图多次调用。

+0

Kudos @BalusC!我删除了两个按钮,并通过“保存文章”按钮替换它们而没有“渲染”。被调用的函数根据editArticle的状态调用createArticle()或updateArticle()。 所以得出的结论是:从来没有把一个动作按钮放在一个表单中并保持getter非常简单? – xentity

回答

1

我想你应该定义托管bean作用域@ViewScoped或其他任何你想要的作用域。 看看这个问题[提问]:What is the default Managed Bean Scope in a JSF 2 application?

+0

嗨,谢谢你的回复@Ahmed。我试过了,但没有区别。甚至没有浏览器选项卡的加载器微调器出现...在浏览器中完全没有任何事情发生。在控制台中,我看到class Article的setTitle()被称为更新后的标题,UploadFilesController也被调用,但不是updateArticle()的调试输出。 – xentity

0

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

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

嗨,谢谢你的回复。正如我在一分钟前写的: 我试过了,但没有区别。甚至没有浏览器选项卡的加载器微调器出现...在浏览器中完全没有任何事情发生。在控制台中,我看到class Article的setTitle()被称为更新后的标题,UploadFilesController也被调用,但不是updateArticle()的调试输出。 – xentity