如果要查看有關JSF / Web應用程序的其他文章,請單擊以下鏈接: 重定向后的JSF持久化對象和消息 , 使用JAAS和JSF進行用戶登錄驗證 , JSF:Converter and Bean AutoComplete , JSF – Hello World,Auto Complete , 在WebApp上處理異常 , 用戶身份驗證(過濾器/ Servlet) , 創建WebServer 。
在本文的結尾,您將找到下載示例源代碼的鏈接。 在本文( 使用JAAS和JSF進行用戶登錄驗證 )中,我展示了如何安裝JBoss 6,以防您從今天開始運行該項目。 您將需要在Eclipse中安裝JBoss工具插件。
看一下下面的頁面及其代碼:

<!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:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html'xmlns:f='http://java.sun.com/jsf/core'>
<h:head>
</h:head>
<h:body><h:form>Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}'/><br /><h:commandButton action='#{user.sayHello}' value='Display my name here, now!'/><br /></h:form>
</h:body>
</html>
我們如何使用Ajax在同一屏幕上顯示鍵入的名稱? 小菜一碟,只需添加“ f:ajax”組件。 檢查代碼更新和結果:


<!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:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html'xmlns:f='http://java.sun.com/jsf/core'>
<h:head>
</h:head>
<h:body><h:form>Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}'/><br /><h:commandButton action='#{user.sayHello}' value='Display my name here, now!'><f:ajax render='myName' execute='inputname' /></h:commandButton><br /><br /><h:outputText id='myName' value='#{user.name}' /></h:form>
</h:body>
</html>
很容易吧? 我們只需要將“ execute”參數傳遞給ManagedBean的值即可; 使用“ render”參數,我們將告知JSF“刷新”哪個組件。
還要注意,鍵入的名稱將出現在控制臺中。
使用此代碼,我們可以“刷新”所有類型的組件。 讓我們看看另一個示例?
如果用戶鍵入的名稱少于4個字符,我們將顯示一條錯誤消息。
檢查我們的新消息和新代碼:

<!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:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html'xmlns:f='http://java.sun.com/jsf/core'>
<h:head>
</h:head>
<h:body><h:form><h:messages id='myMessage' globalOnly='true' showDetail='true'/>Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}'/><br /><h:commandButton action='#{user.sayHello}' value='Display my name here, now!'><f:ajax render='myName myMessage' execute='inputname' /></h:commandButton><br /><br /><h:outputText id='myName' value='#{user.name}' /></h:form>
</h:body>
</html>
package demo;import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;/*** Created by JBoss Tools*/
@ManagedBean(name = 'user')
@RequestScoped
public class User {private String name;public String sayHello() {if (isNameIncorrect()) {FacesContext context = FacesContext.getCurrentInstance();context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Too small', 'Can you write it a little bigger?'));}System.out.println(name);return null;}private boolean isNameIncorrect() {return ''.equals(name.trim()) || name.length() < 3;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
請注意,我們具有“ h:messages”組件,其ID在“ f:ajax”組件中使用。 當您使用“ h:message for =” YYY ”組件時,此代碼也適用。
如果我們現在使用組合框怎么辦? 讓我們顯示一個組合框,當我們使用少于6個字符的名稱時,將包含4個項目;如果鍵入的名稱超過6個字符,則將顯示一個包含4個以上項目的列表。
package demo;import java.util.ArrayList;
import java.util.List;import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UISelectItems;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;/*** Created by JBoss Tools*/
@ManagedBean(name = 'user')
@RequestScoped
public class User {private String name;private List<String> cars;private String selectedCar;private HtmlSelectOneMenu htmlSelectCars;private static final String SELECT_A_CAR = 'Select One Car';public User() {cars = new ArrayList<String>();}public String sayHello() {if (isNameInCorrect()) {FacesContext context = FacesContext.getCurrentInstance();context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Too small', 'Can you write it a little bigger?'));}System.out.println(name);return null;}private boolean isNameInCorrect() {return name == null || ''.equals(name.trim()) || name.length() < 3;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void editMyCarsList(AjaxBehaviorEvent event) {if (htmlSelectCars == null) {htmlSelectCars = new HtmlSelectOneMenu();}htmlSelectCars.getChildren().clear();UISelectItems items = new UISelectItems();items.setValue(getCars());htmlSelectCars.getChildren().add(items);}public List<String> getCars() {cars.clear();cars.add(SELECT_A_CAR);if (!isNameInCorrect() && name.length() >= 6) {cars.add('Ferrari');cars.add('Porch');cars.add('Beetle');cars.add('Opala');cars.add('Passat');cars.add('Vectra');cars.add('Chevet');cars.add('Corvet');} else {cars.add('Ferrari');cars.add('Porch');cars.add('Beetle');cars.add('Opala');}return cars;}public void setCars(List<String> cars) {this.cars = cars;}public String getSelectedCar() {return selectedCar;}public void setSelectedCar(String selectedCar) {this.selectedCar = selectedCar;}public HtmlSelectOneMenu getHtmlSelectCars() {editMyCarsList(null);return htmlSelectCars;}public void setHtmlSelectCars(HtmlSelectOneMenu htmlSelectCars) {this.htmlSelectCars = htmlSelectCars;}
}
現在看一下我們的頁面:


<!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:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html'xmlns:f='http://java.sun.com/jsf/core'>
<h:head>
</h:head>
<h:body><h:form><h:messages id='myMessage' globalOnly='true' showDetail='true' />Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}' /><br /><h:commandButton action='#{user.sayHello}' value='Display my name here, now!'><f:ajax render='myName myCars myMessage' execute='inputname' listener='#{user.editMyCarsList}' /></h:commandButton><br /><br /><h:outputText id='myName' value='#{user.name}' /><br /><br />Choose your car: <h:selectOneMenu id='myCars' binding='#{user.htmlSelectCars}' value='#{user.selectedCar}' /><br /><br /></h:form>
</h:body>
</html>
請注意,我們的組合框項目大小會根據鍵入的名稱進行更新。 在本文的結尾,我將詳細討論為什么我對HtmlSelectOneMenu使用binding屬性而不是返回List <String>。
作為最后一個示例,讓我們創建一個組合框,該組合框將根據Car組合框中的選定值出現和消失。
看看我們的ManagedBean:
package demo;import java.util.ArrayList;
import java.util.List;import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UISelectItems;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;/*** Created by JBoss Tools*/
@ManagedBean(name = 'user')
@RequestScoped
public class User {private String name;private List<String> cars;private List<String> colors;private String selectedCar;private String selectedColor;private HtmlSelectOneMenu htmlSelectCars;private static final String SELECT_A_CAR = 'Select One Car';public User() {cars = new ArrayList<String>();colors = new ArrayList<String>();colors.add('Red');colors.add('Blue');colors.add('Orange');colors.add('Pink --> O.o');}public String sayHello() {if (isNameInCorrect()) {FacesContext context = FacesContext.getCurrentInstance();context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Too small', 'Can you write it a little bigger?'));}System.out.println(name);return null;}private boolean isNameInCorrect() {return name == null || ''.equals(name.trim()) || name.length() < 3;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void editMyCarsList(AjaxBehaviorEvent event) {if (htmlSelectCars == null) {htmlSelectCars = new HtmlSelectOneMenu();}htmlSelectCars.getChildren().clear();UISelectItems items = new UISelectItems();items.setValue(getCars());htmlSelectCars.getChildren().add(items);}public List<String> getCars() {cars.clear();cars.add(SELECT_A_CAR);if (!isNameInCorrect() && name.length() >= 6) {cars.add('Ferrari');cars.add('Porch');cars.add('Beetle');cars.add('Opala');cars.add('Passat');cars.add('Vectra');cars.add('Chevet');cars.add('Corvet');} else {cars.add('Ferrari');cars.add('Porch');cars.add('Beetle');cars.add('Opala');}return cars;}public void setCars(List<String> cars) {this.cars = cars;}public String getSelectedCar() {return selectedCar;}public void setSelectedCar(String selectedCar) {this.selectedCar = selectedCar;}public List<String> getColors() {return colors;}public void setColors(List<String> colors) {this.colors = colors;}public boolean isColorsAlloweToDisplay() {if (isNameInCorrect()) {return false;}if (selectedCar == null || selectedCar.trim().equals('') || selectedCar.equals(SELECT_A_CAR)) {return false;}return true;}public String getSelectedColor() {return selectedColor;}public void setSelectedColor(String selectedColor) {this.selectedColor = selectedColor;}public HtmlSelectOneMenu getHtmlSelectCars() {editMyCarsList(null);return htmlSelectCars;}public void setHtmlSelectCars(HtmlSelectOneMenu htmlSelectCars) {this.htmlSelectCars = htmlSelectCars;}
}
我們的ManagedBean進行了輕微更新,我們只是添加了一個List,該List的方法返回了將填充組合框的顏色列表。 我們還添加了一個方法,該方法將返回布爾值-如果允許顯示組合框,則返回true。
檢查我們的新頁面:


<!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:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html'xmlns:f='http://java.sun.com/jsf/core'>
<h:head>
</h:head>
<h:body><h:form><h:messages id='myMessage' globalOnly='true' showDetail='true' />Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}' /><br /><h:commandButton action='#{user.sayHello}' value='Display my name here, now!'><f:ajax render='myName myCars myMessage myColors' execute='inputname' listener='#{user.editMyCarsList}' /></h:commandButton><br /><br /><h:outputText id='myName' value='#{user.name}' /><br /><br />Choose your car:<h:selectOneMenu id='myCars' binding='#{user.htmlSelectCars}' value='#{user.selectedCar}'><f:ajax render='myColors' execute='inputname myCars'/></h:selectOneMenu><br /><br /><h:panelGroup id='myColors'><h:selectOneMenu value='#{user.selectedColor}' rendered='#{user.colorsAlloweToDisplay}'><f:selectItems value='#{user.colors}' /></h:selectOneMenu></h:panelGroup></h:form></h:body>
</html>
我將討論帖子中使用的代碼:
- HtmlSelectOneMenu –我使用組件而不是列表,因為JSF在用戶屏幕(DOM樹)中呈現組件的效果不是很好。 如果您的組合框有4行,并且使用ajax將更多行添加到列表中,那么JSF / Ajax將無法識別新添加的行; 您將只能使用舊值。 您可以嘗試將代碼與List <String>一起使用,而不是使用HtmlSelectOneMenu來查看結果; 我花了大約3到4個小時來通過互聯網上的大量搜索來了解這一點。
- “ h:panelGroup”組件內的HtmlSelectOneMenu –我這樣做是因為每次您要呈現未呈現的組件時,都需要更新其容器。 如果我們的selectOne位于汽車selectOne的同一窗體內,則需要呈現所有窗體。
單擊此處下載此文章的代碼 。
希望這篇文章對您有所幫助。
如果您有任何疑問/疑問/建議,請將其發布。
參考: uaiHebert博客上來自JCG合作伙伴 Hebert Coelho的JSF Simple Ajax Samples 。
翻譯自: https://www.javacodegeeks.com/2012/07/jsf-simple-ajax-samples.html