2012-07-12 71 views
0

我遇到了純JSF 2頁面的問題。當加載頁面顯示兩個inputText和一個選擇。每個的右側都有一個驗證字段。這兩個輸入是必填字段,而select始終有一個選擇,所以它根本不驗證(至少它不應該)。JBoss AS 7.1.1.Final:serverError:JSF 2視圖驗證類java.lang.IllegalStateException

以下是截圖:

enter image description here

這是被點擊創建按鈕時,顯示的內容。當重新打創建按鈕下面的彈出窗口:

enter image description here

OK,什麼沒有代碼,這裏的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:f="http://java.sun.com/jsf/core" 
     xmlns:h="http://java.sun.com/jsf/html"> 
    <h:head> 
    </h:head> 
    <h:body> 
    <h:form> 
     <h:panelGrid columns="3" id="base-data-grid"> 
     <h:outputLabel value="Name:*" for="name-input" /> 
     <h:inputText value="#{testBean.name}" 
        requiredMessage="Name required!" 
        id="name-input"> 
      <f:validateRequired /> 
     </h:inputText> 
     <h:message for="name-input" style="color: red;" /> 
     <h:outputLabel value="Code:*" for="code-input" /> 
     <h:inputText value="#{testBean.code}" 
        requiredMessage="Code required!" 
        id="code-input"> 
      <f:validateRequired /> 
     </h:inputText> 
     <h:message for="code-input" style="color: red;" /> 
     <h:outputLabel value="Location:" for="location-select" /> 
     <h:selectOneMenu value="#{testBean.location}" 
         converter="#{testConverter}" 
         id="location-select"> 
      <f:selectItems value="#{testBean.locations}" 
         var="l" 
         itemValue="#{l}" 
         itemLabel="#{l.name}" /> 
     </h:selectOneMenu> 
     <h:message for="location-select" style="color: red;" /> 
     </h:panelGrid> 
     <h:panelGrid columns="1"> 
     <h:commandButton value="Create" 
          action="#{testBean.create}"> 
      <f:ajax execute="base-data-grid" render="base-data-grid lalala" /> 
     </h:commandButton> 
     </h:panelGrid> 
     <h:messages id="lalala" /> 
    </h:form> 
    </h:body> 

</html> 

的選擇(只是一個名字)的位置類:

public class Location 
{ 
    private String name; 
    public Location(String name) 
    { 
     this.name = name; 
    } 
    public String getName() 
    { 
     return name; 
    } 
} 

所述的轉換器(如CDI版本):

import javax.enterprise.context.RequestScoped; 
import javax.faces.component.UIComponent; 
import javax.faces.context.FacesContext; 
import javax.faces.convert.Converter; 
import javax.inject.Inject; 
import javax.inject.Named; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

@Named 
@RequestScoped 
public class TestConverter implements Converter 
{ 
    private static final Logger log = LoggerFactory.getLogger(TestConverter.class); 

    @Inject 
    private TestBean testBean; 

    @Override 
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String name) 
    { 
     log.info(getClass().getSimpleName() + ".getAsObject: " + name); 

     return testBean.getLocationFor(name); 
    } 

    @Override 
    public String getAsString(FacesContext arg0, UIComponent arg1, Object obj) 
    { 
     log.info(getClass().getSimpleName() + ".getAsString: " + obj); 

     return ((Location)obj).getName(); 
    } 
} 

而且測試豆:

import java.io.Serializable; 
import java.util.ArrayList; 
import java.util.List; 
import javax.annotation.PostConstruct; 
import javax.enterprise.context.SessionScoped; 
import javax.inject.Named; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

@Named 
@SessionScoped 
public class TestBean implements Serializable 
{ 
    private static final Logger log = LoggerFactory.getLogger(TestBean.class); 

    private String name; 
    private String code; 

    private Location location; 
    private List<Location> locations; 

    @PostConstruct 
    public void init() 
    { 
     locations = new ArrayList<Location>(); 

     locations.add(new Location("Berlin")); 
     locations.add(new Location("London")); 
     locations.add(new Location("New York")); 
     locations.add(new Location("Moscow")); 
     locations.add(new Location("Bejing")); 

     location = locations.get(2); 
    } 

    public String getName() 
    { 
     return name; 
    } 

    public void setName(String name) 
    { 
     this.name = name; 
    } 

    public String getCode() 
    { 
     return code; 
    } 

    public void setCode(String code) 
    { 
     this.code = code; 
    } 

    public Location getLocation() 
    { 
     return location; 
    } 

    public void setLocation(Location location) 
    { 
     this.location = location; 
    } 

    public List<Location> getLocations() 
    { 
     return locations; 
    } 

    public void setLocations(List<Location> locations) 
    { 
     this.locations = locations; 
    } 

    public void create() 
    { 
     log.info("Creating new whatever..."); 
    } 

    // for converter to mimic DB query 
    public Location getLocationFor(String name) 
    { 
     for (Location location : locations) 
     { 
      if (location.getName().equals(name)) 
      { 
       return location; 
      } 
     } 

     return null;  
    } 

} 

正如你所看到的,沒有太多的頁面應該做的事。驗證兩個輸入字段,如果全部驗證正確,則顯示select並調用testBean.create。

但是,一旦驗證運行一次,每個後續的創建按鈕點擊都會導致該serverError。

請注意,如果完全刪除f:selectItems或h:selectOneMenu,頁面將按預期工作。這是什麼讓整個事情真的很奇怪......

我不知道這裏發生了什麼。 有人知道有什麼問題嗎?

我在這裏附加了一個JBoss AS 7測試應用程序:https://community.jboss.org/thread/202501(dupe post,抱歉需要很多幫助)。

請看看這個非常奇怪的IllegalStateException。還有的甚至沒有什麼東西在JBAS server.log中......

PS:在鑽嘴魚科的版本當然是2.1.7(附帶的JBoss AS 7.1.1.Final一)

+0

ajax請求期間發生異常。請找到併發布整個堆棧跟蹤。如果你找不到它,那就是你需要解決的第一個問題。 – BalusC 2012-07-12 03:01:13

+0

呃......發生了異常? JBoss AS 7日誌中沒有任何內容。我從來沒有這樣的情況,那麼我如何找到堆棧跟蹤呢? – Kawu 2012-07-12 08:35:33

+0

您是如何發現在AJAX請求期間拋出異常的? – Kawu 2012-07-12 08:43:15

回答

1

你的問題是,所述Location需要可序列
(實施java.io.Serializable接口)

f:validateRequired標記會導致由AJAX來執行所需要的驗證。

在此ajax-request的RestoreView階段期間,運行時由於Location不是Serializable而遇到InstantiationException。

我確實不知道爲什麼包含堆棧跟蹤的錯誤未被記錄。

+0

本週的英雄!我不知道你是如何能夠發現的,但是非常感謝。我將進一步讓JBoss人員研究爲什麼這不會記錄異常。 – Kawu 2012-07-12 10:00:57

+0

我通過調試發現了根異常。 嘗試在com.sun.faces.lifecycle.LifecycleImpl的execute()方法內部的循環中設置斷點。它對JSF生命週期有很好的學習經驗。 – 2012-07-12 10:17:45