JSF 2.0阅读笔记:视图状态 (四)

五. 实例验证

下面使用GlassFish v3来测试JSF2.0 RI的ViewState情况。

JSF2.0规范中提供了三个上下文参数来指定应用的ViewState策略,可在web.xml文件中使用context-param元素来配置。第一个是从JSF1.2就流传下来的[b]javax.faces.STATE_SAVING_METHOD[/b],取值为server或client,用于配置把视图状态数据放在服务器端还是传递到客户端,默认为server。第二个是[b]javax.faces.PARTIAL_STATE_SAVING[/b],取值为true或false,用于配置是否在应用范围内启用或禁用增量视图状态,默认为true。第三个是[b]javax.faces.FULL_STATE_SAVING_VIEW_IDS[/b],取值为一系列用逗号分隔的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>


修改web.xml为

<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" />


其中视图状态信息是[color=red]1636字节(1.6k)[/color]。现在把web.xml中的javax.faces.PARTIAL_STATE_SAVING上下文参数修改为true,重启应用后刷新页面。可发现视图状态隐藏域变为:

<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" />

其中视图状态信息是[color=red]696字节(0.7k)[/color],减少了[color=red]57%[/color]。

如果把其中form中的内容重复10次

<?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>


在完全视图状态下,视图状态尺寸是[color=red]2248字节[/color](为节省篇幅,不再贴出视图状态原文)。在增量视图状态下,视图状态尺寸是[color=red]752字节[/color],减少约[color=red]66%[/color]。不难算出,在完全视图状态下,重复部分的单位视图状态尺寸是(2248-1636) / (10 - 1) = [color=red]68字节[/color]。而在增量视图状态下,重复部分的单位视图状态尺寸是 (752-696) / (10 - 1) = [color=red]6字节[/color]。随着组件数目的增多,增量视图状态的优势将更为明显。

下面测试Facelet动态页面与编程方式动态页面增量视图状态尺寸差别。

如果使用ui:repeat标签来动态创建组件,如下:

页面

<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>


Bean:

@ManagedBean(name = "viewStateBean")
@RequestScoped
public 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;
}
}


增量视图状态尺寸为[color=red]1068字节[/color]。

如果使用编程方式来动态创建组件,如下:


<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")
@RequestScoped
public 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);
}
}
}


访问页面,点populate按钮后,动态创建出10组Label + 输入框 + 按钮。增量视图状态为[color=red]2124字节[/color]。可以看出,通过编程方式动态创建的组件,视图状态与完全视图状态类似。而通过Facelet的ui:repeat等特性创建的组件,则可享受到增量视图状态的优化。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值