JSF 2.0阅读笔记:视图状态 (四)
五. 实例验证
下面使用GlassFish v3来测试JSF2.0 RI的ViewState情况。
JSF2.0规范中提供了三个上下文参数来指定应用的ViewState策略,可在web.xml文件中使用context-param元素来配置。第一个是从JSF1.2就流传下来的javax.faces.STATE_SAVING_METHOD,取值为server或client,用于配置把视图状态数据放在服务器端还是传递到客户端,默认为server。第二个是javax.faces.PARTIAL_STATE_SAVING,取值为true或false,用于配置是否在应用范围内启用或禁用增量视图状态,默认为true。第三个是javax.faces.FULL_STATE_SAVING_VIEW_IDS,取值为一系列用逗号分隔的ViewId,用于配置当增量视图状态开启时,需要强制保存完全视图状态的页面,默认为空。
首先使用一个简单的页面测试:
<?xml version="1.0" encoding="UTF-8" ?><html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:body> <h:form> <h:outputLabel>name</h:outputLabel> <h:inputText/> <h:commandButton value="submit"/> </h:form> </h:body></html>
<context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> <context-param> <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name> <param-value>false</param-value> </context-param>
<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="H4sIAAAAAAAAAL1WTWwbRRSerJ3/pDRJVYSgURERpJBsYjl2nKa0cdKELHF+VLuBwMEdryfxhv1jdtZZ9xDRCxy4VGo5IAXBgQOHcuLGAQQckJCKBBIXTghxBC6A+LnAm1mvf4TdVXroSDua2Zn33rz3vm/e3PkFdboUjbyc2cdlLOvY3JM3C/tEZfM3v37x3ZPOOV1CyLMRQl0ORXHVMmTHNeVdrBJHxrataypmmmXKWYYZWccm3iNUMWx9LEcJ2bCK5Pfdjz/5cPq5Twe4noNJxNtZbs2ragGdtmUSk8lXlW2NHFyxLIY69/NaMeY5r6JDJB1MCKnRdlKbLrNdhrq4DJsJhGIg0oGeaC1UYoYur0K3YlGjKpkIJFMgKaGnQyR9qxlcIHpVQTJQkBQKxkMUKCbI54gXnDwViJ8X4hMh4kuWYWCzuOgyZplVFXOey1XwJrUYddnQarP+Q4rkdjFdCsZjW9SyCWWVNVJxULUNQzIpOlEHzbLpGo2LNkMDlJhFQgnNVWxSpihatrQiqjfPBvuTYUhoa557cQJCp1sq1gmA86Q4jcs0Xc6If4d/DV07mv77ZwlFFdRTwk5JBTxmULdquSajFYaGBeynuAdTWUY1c28+g3r41AUccwsPw/Yypho2mZh69r/QGJKuZqGDoyJ0yBdGGOr3/V3TmFJkqG81t57JL6azylKwoUvHDqzBUYfqgVNMRoAywz++9/6fN95ISahDQZ1lrLvEC1wS+zZco0Do63feOtN/+4c3A1J21HSXIV7c7qkpPhJsvEwMS/Y4XppNLlqWTrB59yx97bujf34Fky8FJm0UUK8Ok45jQKqbDx5i/sGDtC5axQqkOnE8qG1RrQxOtEj5KcwgVwWXESdXwixNSZYwcHGkDoA0pbiS0Rzm3fj2zNtf4nciPK5RR7tORNyiB1Heg9CTrU8lArhq6ZDQLC4TuvPVR8/eOrq7LiEpg3pVyKSzgY0AIn0O7CkKGYZO+6DSrKksAeDo2nVc0Mm8Z9tlvj0uSJ4Agow236a818EROb21lVGWL4fuW09fWcsr9X1PtXZlW1l+IZ/ZXErnlM2N/NryjidAMwgYrQeyhhARvlXgyjq2O7u//+yL09e+iSBpBfXpFi6uYJVZVEG9rESJU4L4ePalBR8IBz3Q8y/C1V8EjY80HojDUhCTl4ufPh+8+dvzt56RUERBXaqlu4YJ+dE1E/gZtTErVdkG6ga52jbA5rsuwNpkbDY+m0qmUjPxfHJ2LqEm4zG+dh5OkWgTPg2qlHyZ7GJXZyv+z7E0VLRKznqFmH98MLFztLC/4Jet0dbmgRyT09O3xz0BzfFaCbo3eZop09uKMrwqAWXOtaMMXw+/Gf3rhk8fD9ISE9N4AwV89PA+1TC+UENVNzFVBjd4w+JFYeKS+JP+X/olP/28X4LpUODjcvtkxXabA5ioRSdyH5fPUGPURH1u9jwiPI+EeH5sRx+Dry/E0WSi2dFk/fSohX/R+7tw+Zvigbj8KHz9IS7PxJtdTjUev8O3zJqfaVCLtCKGi0ZehDq1HczqUveOWmt+DTeVJPFoeiAxkuEbCIPFtAdsb/PgEwWSv/TCCO/XcIiz4xYMjTVFfY7PDv8DUovXIu8LAAA=" autocomplete="off" />
<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="H4sIAAAAAAAAAJVSQWsTQRR+3SS1DVFqDL3ZUxEEnVAwUAxigmlocKuBrWDxoJPNtDtxdnecebvZ9FDwHwiehIpXD976C8SDICjo0f/gTe/ObGLTgx4cmLezb+a9933vfe9+QElqBRdHNKUkQS7INtXBDpWlc9/ff1h98rUAThfKIqbDLvUxVj1YxkAxHcRimMnbLbCrMl4ydsXsAsLi6DEf4o1EwaVHbp5X0OiA3B+MmI/NF18evlnRV4UDkEkT4CTP4AgK5lSSZs3/jhQQG52RfeozTfw4lHHEIiQPenf+nNf7KpZM4eQum2iYrapJreDCvPRWlIRnLyVCmSIqPkiQaW1LwozJYs7E7gWENVOT6CSaIbBWMNSk3e+7va2O6VvjHy94KAXpsH2aCOxOnettKcVkN37Kol9vr+0dt0atisUyXoNaPeVs7CFF1mFhTLIAQ2EQXN9onvzMMtOJxv91oq94apKd5WxJLiHU5rx3A4ptxTyD14xqLoC2UnTico3Z82+XX32krwuw0IOi5odsOrFx0VoTdOXvqHIi20YfTHk0ZWrv08mtl8efdxxwXFj2BdX6Hg0ZQjWXR93OqO4ZWNFB04WyNjHDPAfC6vQFj+seU5wKfkgHgjUzKVNLqJrPriatrRgnwvlcfI2b+WfzVE1Fqy2EknVvnHodKbPf9nnPfQIDAAA=" autocomplete="off" />
<?xml version="1.0" encoding="UTF-8" ?><html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:body> <h:form> <h:outputLabel>name</h:outputLabel> <h:inputText/> <h:commandButton value="submit"/> <br/> <h:outputLabel>name</h:outputLabel> <h:inputText/> <h:commandButton value="submit"/> <br/> ...重复10次 </h:form> </h:body></html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:body> <h:form> <ui:repeat value="#{viewStateBean.range}" var="idx"> <h:outputLabel>name#{idx}</h:outputLabel> <h:inputText/> <h:commandButton value="submit"/> <br/> </ui:repeat> </h:form> </h:body></html> @ManagedBean(name = "viewStateBean")@RequestScopedpublic class ViewStateDemoBean { private List<Integer> range = new AbstractList() { @Override public Object get(int index) { return index; } @Override public int size() { return 10; } }; public List<Integer> getRange() { return this.range; }}<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:body> <h:form binding="#{viewStateBean.form}"> <h:commandButton actionListener="#{viewStateBean.populateForm}" value="populate"/> </h:form> </h:body></html> @ManagedBean(name = "viewStateBean")@RequestScopedpublic class ViewStateDemoBean { private UIComponent form; public void setForm(UIComponent form) { this.form = form; } public UIComponent getForm() { return this.form; } public void populateForm(ActionEvent e) { List<UIComponent> children = form.getChildren(); Application app = FacesContext.getCurrentInstance().getApplication(); children.clear(); UIComponent c; for (int i = 0; i < 10; i++) { c = app.createComponent(HtmlOutputLabel.COMPONENT_TYPE); c.getAttributes().put("value", String.format("name%s", i)); children.add(c); c = app.createComponent(HtmlInputText.COMPONENT_TYPE); children.add(c); c = app.createComponent(HtmlCommandButton.COMPONENT_TYPE); c.getAttributes().put("value", "submit"); children.add(c); c = app.createComponent(HtmlOutputText.COMPONENT_TYPE); c.getAttributes().put("value", "<br/>"); c.getAttributes().put("escape", false); children.add(c); } }}