jsf教程_JSF范围教程– JSF / CDI会话范围
jsf教程
会话作用域跨越多个HTTP请求-响应周期(理论上是无限的)。
当您需要每个HTTP请求-响应周期进行一次交互时,请求作用域在任何Web应用程序中都非常有用。 但是,当您需要对属于用户会话的任何HTTP请求-响应周期可见的对象时,则需要一个会话范围 ; 在这种情况下,只要HTTP会话存在,该bean就一直存在。 会话作用域允许您创建对象并将其绑定到会话。 它在会话中涉及此bean的第一个HTTP请求时创建,并在HTTP会话无效时销毁。 请求范围存在于JSF和CDI中,并且以相同的方式起作用。 它可以用于非富AJAX和非AJAX请求。
会话范围注释
JSF :JSF请求范围注释是@SessionScoped
( javax.faces.bean.SessionScoped
)。 具有此范围的bean应该使用@ManagedBean
( javax.faces.bean.ManagedBean
)进行注释。 默认范围是@RequestScope
。
CDI :CDI请求范围注释为@SessionScoped
( javax.enterprise.context.SessionScoped
)。 具有此范围的bean应该用@Named
( javax.inject.Named
)注释。 对于CDI托管bean( @Named
),默认范围是@Dependent
伪作用域。
简单的例子
// index.xhtml
<h:body> <h4>Same view after submit (index.xhtml):</h4><h:form><h:commandButton value="Count" action="#{countBean.countActionVoid()}"/></h:form>Current value: #{countBean.count}<h4>Forward to another view after submit (count.xhtml):</h4><h:form><h:commandButton value="Count" action="#{countBean.countActionAndForward()}"/></h:form>Current value: #{countBean.count}<h4>Redirect to another view after submit (count.xhtml):</h4><h:form><h:commandButton value="Count" action="#{countBean.countActionAndRedirect()}"/></h:form>Current value: #{countBean.count}<h4>AJAX :</h4><h:form><h:commandButton value="Count" action="#{countBean.countActionVoid()}"><f:ajax render="currentValueId"/></h:commandButton></h:form><h:outputText id="currentValueId" value="Current value: #{countBean.count}"/>
</h:body>// count.xhtml
<h:body> Current value: #{countBean.count}
</h:body>// CountBean.java
import java.util.logging.Logger;
import java.io.Serializable;
// for JSF
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
// for CDI
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;// JSF vs CDI
@ManagedBean @Named
@SessionScoped @SessionScoped
public class CountBean implements Serializable {private static final Logger LOG = Logger.getLogger(CountBean.class.getName());private int count;public CountBean() {LOG.info("CountBean#Initializing counter ...");count = 0;}public void countActionVoid() {LOG.info("CountBean#countActionVoid() - Increasing counter ...");count++;}public String countActionAndForward() {LOG.info("CountBean#countActionAndForward() - Increasing counter ...");count++;return "count";}public String countActionAndRedirect() {LOG.info("CountBean#countActionAndRedirect() - Increasing counter ...");count++;return "count?faces-redirect=true;";}public int getCount() {return count;}public void setCount(int count) {this.count = count;}
}
完整的应用程序可在此处获得 。
因此,当通过AJAX,在同一视图(或另一个视图)或重定向机制中通过前进机制返回时, count
数值将增加1
。 这揭示了两个方面:
- 每个用户会话一次调用
CountBean
构造函数以创建一个新实例。 这意味着count
仅用0
初始化一次。 当前用户会话中触发的其他请求将使用此CountBean
实例。 我们说每个用户都有一个CountBean
实例。 - 会话范围在转发或重定向时不会丢失对象的状态。 在
session
被销毁之前,对象的状态一直可用(例如,会话超时,无效等)。
基本上,在将数据提交到会话作用域的bean时必须要注意。 只要当前的用户会话,提交的数据将“有效”。 因此,一个好的实践将告诉您不要在会话中存储大量数据,尤其是在内存是关键资源的情况下。
实现可序列化
JSF和CDI托管bean应该声明为Serializable
( implements Serializable
)。 这是必需的,因为容器可能会将会话数据持久化(序列化)到硬盘上。 这样,容器可以管理重载之类的紧急情况,或者仅与集群中的其他服务器共享数据,或者在服务器重启期间恢复会话。
会话范围编程访问
您可以通过编程方式与会话范围进行交互,如下所示:
- 访问会话范围图
// JSF 2.0-2.2 FacesContext context = FacesContext.getCurrentInstance(); Map<String, Object> requestMap = context.getExternalContext().getSessionMap();// JSF 2.3 @Inject @SessionMap private Map<String, Object> sessionMap;// OmniFaces Map<String, Object> requestmap = Faces.getSessionMap();
- 获取会话范围的属性
// JSF 2.0 - 2.3 sessionMap.put(name, value);// OmniFaces Faces.setSessionAttribute(name, value);
- 删除会话范围的属性
// JSF 2.0-2.3 Object value = sessionMap.remove(name);// OmniFaces <T> value = Faces.removeSessionAttribute(name);
! 在JSF页面中,可以使用隐式对象#{sessionScope}
(例如,获取CountBean
实例: #{sessionScope.countBean}
)。
其中,会话映射将包含在会话范围( @SessionScoped (JSF/CDI
))下声明的托管bean实例。
如果是JSF托管Bean(不是CDI托管Bean,在这种情况下,密钥非常复杂),则可以通过它们的名称轻松识别此类Bean,这些名称在会话映射中成为密钥。 因此,您将能够在会话映射中的countBean
项下找到该JSF托管Bean的实例。 如果通过@ManagedBean
(名称=“ some_name ”)指定bean名称,则some_name将成为会话映射中的键。 因此,通过会话映射,您可以访问会话范围内的JSF托管Bean的属性,如下所示:
String count = ((CountBean)(Faces.getSessionAttribute("countBean/some_name"))).getCount();
这样做也是完全合法的(这是指当前的bean):
@ManagedBean(name="some_name")
...
String bean_name = getClass().getAnnotation(ManagedBean.class).name();
int count = ((CountBean)(Faces.getSessionAttribute(bean_name))).getCount();
现在,您可以轻松地了解如何使用存储在会话映射中的托管bean。
使用
通常,在托管bean中,我们需要编写一个带有@PostConstruct
注释的方法,以基于注入的工件来完成初始化任务。 换句话说,@ @PostConstruct
注释用于需要依赖注入完成以执行任何初始化之后需要执行的方法。 当初始化不涉及注入的工件时,可以使用构造函数进行初始化。 对于会话作用域的Bean,在创建会话作用域的Bean实例之后,将仅调用一次用@PostConstruct
注释的方法。
JSF托管bean示例:
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;@ManagedBean
@SessionScoped
public class InitBean implements Serializable{private int init;public InitBean() {init = 5;}public int getInit() {return init;}public void setInit(int init) {this.init = init;}
}import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;@ManagedBean
@SessionScoped
public class CountBean implements Serializable {@ManagedProperty("#{initBean}")private InitBean initBean;@PostConstructpublic void init(){LOG.info("CountBean#Initializing counter with @PostConstruct ...");count = initBean.getInit();}public void setInitBean(InitBean initBean) {this.initBean = initBean;} ...
}
CDI托管Bean示例:
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;@Named
@SessionScoped
public class InitBean implements Serializable {private int init;public InitBean() {init = 5;}public int getInit() {return init;}public void setInit(int init) {this.init = init;}
}import java.io.Serializable;
import javax.inject.Inject;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;@Named
@SessionScoped
public class CountBean implements Serializable {@Injectprivate InitBean initBean;@PostConstructpublic void init(){LOG.info("CountBean#Initializing counter with @PostConstruct ...");count = initBean.getInit();}...
}
注入和会话作用域bean
JSF :对于JSF托管的bean,注入是通过@ManagedProperty
完成的。 例如:
CDI :对于CDI托管的bean,注入是通过@Named
完成的。 例如:
JSF和CDI混合:可以在JSF中注入CDI(反之亦然!)
JSF托管Bean限制:
! 作为JSF中的一般规则,请勿使用寿命比调用它的对象更短的对象。 换句话说,请使用寿命与被注入对象相同或更长的对象。 违反此规则将导致JSF异常。 根据此规则,在JSF会话范围内的受管Bean中,您可以注入会话和应用程序受管Bean,但不能请求或查看受管Bean。 可以将JSF托管Bean注入其他JSF托管Bean中。
CDI托管Bean限制:
! 当使用寿命比调用它的对象更短的对象时(例如,将请求范围的Bean注入会话范围的Bean),CDI将用例分类为不匹配的注入,并通过CDI解决问题代理。 对于每个请求,CDI代理都会重新建立与请求范围的Bean的实时实例的连接。 可以将CDI托管bean注入JSF托管bean中。
以编程方式配置JSF会话范围的托管Bean
从JSF 2.2开始,我们可以以编程方式重现faces-config.xml
的内容。 对于会话范围内的受管bean,相关的代码片段为:
@Override
public void populateApplicationConfiguration (Document toPopulate) {String ns = toPopulate.getDocumentElement().getNamespaceURI();Element managedbeanEl = toPopulate.createElementNS(ns, "managed-bean");Element managedbeannameEl = toPopulate.createElementNS(ns, "managed-bean-name");managedbeannameEl.appendChild(toPopulate.createTextNode("countBean"));managedbeanEl.appendChild(managedbeannameEl);Element managedbeanclassEl = toPopulate.createElementNS(ns, "managed-bean-class");managedbeanclassEl.appendChild(toPopulate.createTextNode("beans.CountBean"));managedbeanEl.appendChild(managedbeanclassEl);Element managedbeanscopeEl = toPopulate. createElementNS(ns, "managed-bean-scope");managedbeanscopeEl.appendChild(toPopulate. createTextNode("session"));managedbeanEl.appendChild(managedbeanscopeEl);...// programmatic create managed-property...toPopulate.getDocumentElement().appendChild(managedbeanEl);
}
完整的应用程序可以在精通JSF 2.2的书中看到。
在XML文件中配置JSF请求范围的托管Bean
通过XML配置,您可以使用旧的JSF 1.x机制在普通的faces-config.xml
文件中定义托管bean。 例如:
...
<managed-bean><managed-bean-name>countBean</managed-bean-name><managed-bean-class>beans.CountBean</managed-bean-class><managed-bean-scope>session</managed-bean-scope>...<!-- managed bean properties --> via <managed-property/>...
</managed-bean>
...
受管bean应该在单独的XML文件中定义,因为faces-config.xml
用于设置应用程序级别的配置。 基本上,如果您喜欢这种方法,请创建一个新的XML文件,并将受管bean的详细信息放入其中。 最后,通过web.xml
文件中的javax.faces.CONFIG_FILES
上下文参数声明XML文件。
...
<context-param><param-name>javax.faces.CONFIG_FILES</param-name><param-value>WEB-INF/my-manage-beans.xml</param-value>
</context-param>
...
在下一篇关于JSF / CDI应用程序范围的文章中见。
翻译自: https://www.javacodegeeks.com/2015/11/jsf-scopes-tutorial-jsfcdi-session-scope.html
jsf教程
jsf教程_JSF范围教程– JSF / CDI会话范围相关推荐
- jsf 教学_JSF初学者教程
jsf 教学 Welcome to JSF Tutorial for Beginners. Java Server Faces (JSF) technology is a front end fram ...
- java jsf教程_JSF入门教程
1. 什么是 Java Server Faces(jsf)? JSF为JAVA的 Web应用用户界面的开发人员提供了标准的编程接口.丰富可扩展的UI组件库(一个核心的JSP标记库用来处理事件.执行验证 ...
- JSF范围教程– JSF / CDI会话范围
会话作用域跨越多个HTTP请求-响应周期(理论上是无限的). 当您需要每个HTTP请求-响应周期进行一次交互时,请求作用域在任何Web应用程序中都非常有用. 但是,当您需要对属于用户会话的任何HTTP ...
- jsf教程_JSF教程
jsf教程 Welcome to JSF Tutorial. Java Server Faces (JSF) technology is a front end framework which mak ...
- jsf 导航_JSF页面导航示例教程
jsf 导航 Page navigation is the redirection of a page based on the events performed for instance – on ...
- jsf 自定义属性_JSF资源包,自定义消息示例教程
jsf 自定义属性 In my earlier posts, I explained how to get started with JSF2 and work with JSF View pages ...
- jsf 配置_JSF Tomcat配置示例
jsf 配置 JavaServer Faces (JSF)是一个Web应用程序框架,旨在简化基于Web的用户界面的开发集成. 它用于开发和构建服务器端用户界面组件,并在Web应用程序中使用它们. JS ...
- jsf el 表达式_JSF表达式语言– JSF EL
jsf el 表达式 JSF Expression Language enables users to access the data dynamically from the JavaBeans c ...
- jsf服务_JSF ManagedBean ManagedProperty
jsf服务 JSF ManagedBean is a java class that can be accessed by the JSF page for retrieving the values ...
最新文章
- 在卷积层的运用_Conv 卷积层
- teststand调用python模块_TestStand 基本知识[10]--在序列中调用代码模块之--LabVIEW
- oracle字段加约束,Oracle数据库的字段约束创建和维护示例
- C++远征之封装篇——常对象成员、常成员函数
- layui导航栏页面滚动固定_网站建设页面导航如何降低用户寻找的时间
- 开源cms 和 开源博客_BackBee CMS如何以及为何开源
- MySQL 每秒 570000 的写入,如何实现?
- python发邮件图片太长显示不出来_Python电子邮件图像太长,无法显示,为什么Python在发送多图表电子邮件时只显示第一个图像?,python,发邮件,图片,不,出来,第一张...
- educoder Scala面向对象编程
- 服务器多开虚拟机怎么使用教程,游戏多开,你需要这个虚拟机教程
- 科学的软件测试培训时间是多久?
- Android项目实战(八):列表右侧边栏拼音展示效果
- html标签的message,Message 消息提示
- 计算机显卡(GPU)基础介绍
- MatrikonOPC与欧姆龙PLC以太网通讯
- c语言程序设计教程中国农业出版社答案,C语言程序设计教程杨路明课后习题答案北京邮电大学出版社.pdf...
- EDEM入门学习教程—界面介绍
- java前端提示反射型xss_搜索框反射型xss问题解决(网站开发)
- 基于DHCP和NAT的家庭网络设备间通信解决方案
- 特斯拉(Tesla)
热门文章
- 强连通分量:洛谷P3387 模板:缩点
- U102488-傻叉题【dp】
- nssl1338-逃亡路径【最短路计数,bfs】
- jzoj4800-[GDOI2017模拟9.24]周末晚会【dp,循环重构】
- jzoj3086,luogu3831-[SHOI2012]回家的路【最短路,拆点】
- P3391-[模板]文艺平衡树【Splay】
- 2021牛客暑期多校训练营3 C-Minimum grid(二分图)
- 【模板】最大权闭合图
- 【DP】Rotating Substrings(CF1363F)
- 初一模拟赛总结(2019.6.1)