基于selectOneMenu值更新JSF数据表

时间:2009-10-19 19:06:19

标签: java jsf

我正在尝试创建一个JSF页面,用户在两个selectOneMenu组件中选择值。然后,这些选择中的值将传递给SQL查询以更新页面上显示的表。

我已将每个选择项绑定到支持bean中的相应变量,但在更改selectOneMenu中选择的值后,支持bean中的bound属性不会更改,并且查询已执行但不会执行t返回任何结果。 (另外,当最初显示页面时,getter似乎也会被调用两次。)

我不能使用任何其他第三方组件(例如RichFaces等)来实现此实现。

对此有任何见解表示赞赏!

以下是代码:

notes.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <title></title>
 </head>
<body>

<f:view>

<h:form id="notelistform">
    <f:subview id="loginbar">
        <jsp:include page="/jsp/loginbar.jsp" />
    </f:subview>

    <h:outputText value="Worktype:" />
    <h:selectOneMenu value="#{pc_noteListBacker.worktype}"
        title="worktype" id="worktypeList" onchange="submit()">
        <f:selectItems value="#{pc_noteListBacker.selectWorktypes}" />
        <f:valueChangeListener
            type="<package>.web.backer.note.NoteListBacker" />

    </h:selectOneMenu>

    <h:outputText value="Product:" />
    <h:selectOneMenu value="#{pc_noteListBacker.product}" title="product"
        id="productList" onchange="submit()">
        <f:selectItems value="#{pc_noteListBacker.selectProducts}" />
        <f:valueChangeListener
            type="<package>.web.backer.note.NoteListBacker" />
    </h:selectOneMenu>


    <h:dataTable id="notelisttable" value="#{pc_noteListBacker.noteList}"
        var="item" bgcolor="#F1F1F1" border="10" cellpadding="5"
        cellspacing="3" first="0" width="80%" dir="LTR" frame="hsides"
        rules="all" summary="Status and notes note table display."
        binding="#{pc_noteListBacker.noteListTable}">


        <h:column>
            <f:facet name="header">
                <h:outputText value="Note ID" />
            </f:facet>
            <h:outputText value="#{item.noteId}"></h:outputText>
        </h:column>


        <h:column>
            <f:facet name="header">
                <h:outputText value="Note Category" />
            </f:facet>
            <h:outputText value="#{item.noteCategory}"></h:outputText>
            <f:facet name="footer">
                <h:commandButton value="Add" action="#{pc_noteListBacker.insert}">
                </h:commandButton>
            </f:facet>
        </h:column>

        <h:column>
            <f:facet name="header">
                <h:outputText value="Note Subcategory" />
            </f:facet>
            <h:outputText value="#{item.noteSubCategory}"></h:outputText>
        </h:column>


        <h:column>
            <f:facet name="header">
                <h:outputText value="Note" />
            </f:facet>
            <h:outputText value="#{item.note}"></h:outputText>
        </h:column>



        <h:column>
            <h:commandButton value="Edit" action="#{pc_noteListBacker.edit}">
            </h:commandButton>
        </h:column>
        <h:column>
            <h:commandButton value="Delete" action="#{pc_noteListBacker.delete}"></h:commandButton>
        </h:column>
    </h:dataTable>

</h:form>

NoteListBacker.java

 package <package>.web.backer.note;

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

 import javax.faces.component.UIComponent;
 import javax.faces.component.UIComponentBase;
 import javax.faces.component.UIData;
 import javax.faces.context.FacesContext;
 import javax.faces.event.AbortProcessingException;
 import javax.faces.event.ValueChangeEvent;
 import javax.faces.event.ValueChangeListener;
 import javax.faces.model.ListDataModel;
 import javax.faces.model.SelectItem;
 import javax.swing.JOptionPane;


 public class NoteListBacker implements ValueChangeListener {

private UIData noteListTable;

private Note note;

private NoteCategory noteCategory;

private NoteSubCategory noteSubCategory;

private NoteDao nDao;

private SybaseSqlDao sybaseDao;

private List<Note> noteList;

private List<SelectItem> selectWorktypes;

private List<SelectItem> selectProducts;

private String worktype;

private List<String> worktypeList;

private String product;

private List<Product> productList;

private int noteId;

public NoteListBacker() {

    nDao = new NoteDao();
    sybaseDao = new SybaseSqlDao();
    selectWorktypes = new ArrayList<SelectItem>();
    selectProducts = new ArrayList<SelectItem>();
    noteList = new ArrayList<Note>();
    note = new Note();
    worktypeList = new ArrayList<String>();
    productList = new ArrayList<Product>();
}

public String insert() {
    return "success";
}

public String save() {
    return "notes";
}

public String edit() {
    return "success";
}

public String update() {
    return "notes";
}

public String delete() {
    Note delNote = (Note) noteListTable.getRowData();
    nDao.deleteNote(delNote);
    return "notes";
}

public String cancel() {
    return "notes";
}

public Note getNote() {
    return note;
}

public void setNote(Note note) {
    this.note = note;
}

public NoteDao getNDao() {
    return nDao;
}

public UIData getNoteListTable() {
    return noteListTable;
}

public void setNoteListTable(UIData noteListTable) {
    this.noteListTable = noteListTable;
}

public List<Note> getNoteList() {


    noteList = nDao.selectNotes(worktype, product); //
    return noteList;
}

public void setNoteList(List<Note> noteList) {
    this.noteList = noteList;
}

public void setNDao(NoteDao dao) {
    nDao = dao;
}

public String getProduct() {
    return product;
}

public void setProduct(String product) {
    this.product = product;
}

public String getWorktype() {
    return worktype;
}

public void setWorktype(String worktype) {
    this.worktype = worktype;
}

public NoteCategory getNoteCategory() {
    return noteCategory;
}

public void setNoteCategory(NoteCategory noteCategory) {
    this.noteCategory = noteCategory;
}

public NoteSubCategory getNoteSubCategory() {
    return noteSubCategory;
}

public void setNoteSubCategory(NoteSubCategory noteSubCategory) {
    this.noteSubCategory = noteSubCategory;
}

public int getNoteId() {
    return noteId;
}

public void setNoteId(int noteId) {
    this.noteId = noteId;
}

public SybaseSqlDao getSybaseDao() {
    return sybaseDao;
}

public void setSybaseDao(SybaseSqlDao sybaseDao) {
    this.sybaseDao = sybaseDao;
}

public List<SelectItem> getSelectWorktypes() {
    selectWorktypes.clear();

    worktypeList = this.getWorktypeList();

    for (String strt : worktypeList) {

        SelectItem si = new SelectItem();
        si.setValue(strt);
        si.setLabel(strt);
        si.setDescription(strt);
        selectWorktypes.add(si);
    }

    return selectWorktypes;
}

public void setSelectWorktypes(List<SelectItem> selectWorktypes) {

    this.selectWorktypes = selectWorktypes;
}

public List<String> getWorktypeList() {

    worktypeList = sybaseDao.selectWorktypes();
    return worktypeList;
}

public void setWorktypeList(List<String> worktypeList) {
    this.worktypeList = worktypeList;
}

public List<Product> getProductList() {

    productList = sybaseDao.selectProducts();
    return productList;
}

public void setProductList(List<Product> productList) {
    this.productList = productList;
}

public List<SelectItem> getSelectProducts() {
    selectProducts.clear();

    productList = this.getProductList();

    for (Product prod : productList) {

        SelectItem si = new SelectItem();
        si.setValue(prod);
        si.setLabel(prod.toString());
        si.setDescription(prod.toString());
        selectProducts.add(si);
    }

    return selectProducts;
}

public void setSelectProducts(List<SelectItem> selectProducts) {
    this.selectProducts = selectProducts;
}

public void processValueChange(ValueChangeEvent arg0) {

    if (arg0.getComponent().getId().equalsIgnoreCase("productList")) {
        this.setProduct(arg0.getNewValue().toString());

    }
    if (arg0.getComponent().getId().equalsIgnoreCase("worktypeList")) {
        this.setWorktype(arg0.getNewValue().toString());
    }

}

 }

faces-config.xml中

 <?xml version="1.0"?>

 <!DOCTYPE faces-config PUBLIC
   "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
   "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">

 <faces-config>

<lifecycle>
    <phase-listener>
        <package>.utils.NoCachePhaseListener
    </phase-listener>
</lifecycle>

<managed-bean>
    <managed-bean-name>pc_userBacker</managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.UserBacker
    </managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>pc_noteCategoryListBacker</managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.note.NoteCategoryListBacker
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>
        pc_noteSubCategoryListBacker
    </managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.note.NoteSubCategoryListBacker
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>pc_noteListBacker</managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.note.NoteListBacker
    </managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>pc_statusListBacker</managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.status.StatusListBacker
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>pc_statusReasonBacker</managed-bean-name>
    <managed-bean-class>
        <package>.web.backer.status.StatusReasonBacker
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>


<!-- Notes -->
<navigation-rule>
    <from-view-id>/jsp/notes/notes.jsp</from-view-id>
    <navigation-case>
        <from-action>#{pc_noteListBacker.edit}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/noteedit.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-action>#{pc_noteListBacker.insert}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/notenew.jsp</to-view-id>
    </navigation-case>


</navigation-rule>


<!-- Note Categories -->
<navigation-rule>
    <from-view-id>/jsp/notes/notecategories.jsp</from-view-id>
    <navigation-case>
        <from-action>#{pc_noteCategoryListBacker.edit}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/notecategoryedit.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-action>
            #{pc_noteCategoryListBacker.insert}
        </from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/notecategorynew.jsp</to-view-id>
    </navigation-case>


</navigation-rule>

<!-- Note Subcategories -->
<navigation-rule>
    <from-view-id>/jsp/notes/notesubcategories.jsp</from-view-id>
    <navigation-case>
        <from-action>
            #{pc_noteSubCategoryListBacker.edit}
        </from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/notesubcategoryedit.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-action>
            #{pc_noteSubCategoryListBacker.insert}
        </from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/notes/notesubcategorynew.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

<!-- Statuses -->
<navigation-rule>
    <from-view-id>/jsp/statuses/statuses.jsp</from-view-id>
    <navigation-case>
        <from-action>#{pc_statusListBacker.edit}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/statuses/statusedit.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-action>#{pc_statusListBacker.insert}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/statuses/statusnew.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

<!-- Status Reasons -->
<navigation-rule>
    <from-view-id>/jsp/statuses/statusreasons.jsp</from-view-id>
    <navigation-case>
        <from-action>#{pc_statusReasonBacker.edit}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/statuses/statusreasonedit.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-action>#{pc_statusReasonBacker.insert}</from-action>
        <from-outcome>success</from-outcome>
        <to-view-id>/jsp/statuses/statusreasonnew.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

<!-- static and general actions-->
<!-- what page the action is coming from doesn't matter here -->
<navigation-rule>

    <navigation-case>
        <from-outcome>login</from-outcome>
        <to-view-id>/login.jsp</to-view-id>
    </navigation-case>

    <navigation-case>
        <from-outcome>menu</from-outcome>
        <to-view-id>/menu.jsp</to-view-id>
    </navigation-case>

    <!-- Notes -->
    <navigation-case>
        <from-outcome>notes</from-outcome>
        <to-view-id>/jsp/notes/notes.jsp</to-view-id>
    </navigation-case>


    <!-- Note Categories -->
    <navigation-case>
        <from-outcome>notecategories</from-outcome>
        <to-view-id>/jsp/notes/notecategories.jsp</to-view-id>
    </navigation-case>

    <!-- Note Subcategories -->
    <navigation-case>
        <from-outcome>notesubcategories</from-outcome>
        <to-view-id>/jsp/notes/notesubcategories.jsp</to-view-id>
    </navigation-case>

    <!-- Statuses -->
    <navigation-case>
        <from-outcome>statuses</from-outcome>
        <to-view-id>/jsp/statuses/statuses.jsp</to-view-id>
    </navigation-case>



    <!-- Status Reasons -->
    <navigation-case>
        <from-outcome>statusreasons</from-outcome>
        <to-view-id>/jsp/statuses/statusreasons.jsp</to-view-id>
    </navigation-case>


</navigation-rule>
 </faces-config>

2 个答案:

答案 0 :(得分:1)

我只是看了一眼代码,但我猜这部分问题可能就在这里:

public void processValueChange(ValueChangeEvent arg0) {
        if (arg0.getComponent().getId().equalsIgnoreCase("productList")) {
                this.setProduct(arg0.getNewValue().toString());

        }
        if (arg0.getComponent().getId().equalsIgnoreCase("worktypeList")) {
                this.setWorktype(arg0.getNewValue().toString());
        }
}

如果您阅读了valueChangeListener type属性的文档,则说明了这一点:

  

要创建和注册的ValueChangeListener的完全限定Java类名。

这意味着您将至少有三个<package>.web.backer.note.NoteListBacker实例 - 两个创建为侦听器,第三个创建为托管bean。最后一个是表绑定的唯一一个,并且侦听器中的任何状态更改都是无关紧要的。

修复:

  1. 没有NoteListBacker实施ValueChangeListener;没有意义。
  2. selectOneMenuvalueChangeListener属性绑定到#{pc_noteListBacker.valueChange}方法(有关详细信息,请参阅文档)有一个单独的ValueChangeListener使用pc_noteListBacker直接从会话中查找FacesContext的实现。

答案 1 :(得分:1)

我经常碰到这个,直到我知道这里的问题是什么。提交页面时,JSF将在您调用processValueChange()之后运行UPDATE_MODEL阶段。因此,对BackingBean的更改将被HTTP请求中的值覆盖,并且不起作用。

要防止这种情况发生,您必须在ValueChangeListener中手动发出导航案例。您可以通过在processValueChange()的末尾插入以下行来完成此操作。

FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(
                FacesContext.getCurrentInstance(), null, "stay_here");

“stay_here”是指faces-config.xml

中的导航案例
<!-- Notes -->
<navigation-rule>
        <from-view-id>/jsp/notes/notes.jsp</from-view-id>
        <navigation-case>
                <from-action>#{pc_noteListBacker.edit}</from-action>
                <from-outcome>success</from-outcome>
                <to-view-id>/jsp/notes/noteedit.jsp</to-view-id>
        </navigation-case>
        <navigation-case>
                <from-action>#{pc_noteListBacker.insert}</from-action>
                <from-outcome>success</from-outcome>
                <to-view-id>/jsp/notes/notenew.jsp</to-view-id>
        </navigation-case>
        <navigation-case>
                <from-outcome>stay_here</from-outcome>
                <to-view-id>/jsp/notes/notes.jsp</to-view-id>
        </navigation-case>

</navigation-rule>

希望这有帮助。

此致