JSF范围教程– JSF / CDI会话范围

会话作用域跨越多个HTTP请求-响应周期(理论上是无限的)。

jsf cdi omnifaces和deltaspike范围-会话范围

当您需要每个HTTP请求-响应周期进行一次交互时,请求作用域在任何Web应用程序中都非常有用。 但是,当您需要对属于用户会话的任何HTTP请求-响应周期可见的对象时,则需要一个会话范围 ; 在这种情况下,只要HTTP会话存在,该bean就一直存在。 会话作用域允许您创建对象并将其绑定到会话。 它在会话中涉及此bean的第一个HTTP请求时创建,并在HTTP会话无效时销毁。 请求范围存在于JSF和CDI中,并且以相同的方式起作用。 它可以用于非富AJAX和非AJAX请求。

会话范围注释

JSF :JSF请求范围注释是@SessionScopedjavax.faces.bean.SessionScoped )。 具有此范围的bean应该使用@ManagedBeanjavax.faces.bean.ManagedBean )进行注释。 默认范围是@RequestScope

CDI :CDI请求范围注释为@SessionScopedjavax.enterprise.context.SessionScoped )。 具有此范围的bean应该用@Namedjavax.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应该声明为Serializableimplements 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 (name =” 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完成的。 例如:

注射JSF 1次

注入JSF 2会话

CDI :对于CDI管理的bean,注入是通过@Named完成的。 例如:

注射CDI 1次

注射CDI 2次

JSF和CDI混合:可以在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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/355324.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css 关闭按钮实现,CSS做的关闭按钮动效

CSS语言&#xff1a;CSSSCSS确定* {padding: 0;margin: 0;box-sizing: border-box;}body {background: #141926;font-family: Helvetica, Arial, sans-serif;}.outer {position: relative;margin: auto;width: 70px;margin-top: 200px;cursor: pointer;}.inner {width: inherit…

数字通信原理_光耦继电器在实际应用中的作用以及工作原理!

光耦继电器---先进光半导体由于光耦继电器输入输出间互相隔离&#xff0c;电信号传输具有单向性等特点&#xff0c;因而具有良好的电绝缘能力和抗干扰能力。又由于光耦的输入端属于电流型工作的低阻元件&#xff0c;因而具有很强的共模抑制能力。所以&#xff0c;它在长线传输信…

网页布局

网页布局 网页布局方面是凌乱的&#xff0c;做出来的成果会漂浮&#xff0c;超出理想的效果&#xff0c;posted on 2017-06-25 16:02 大师放放 阅读(...) 评论(...) 编辑 收藏 转载于:https://www.cnblogs.com/shujie/p/7077027.html

css的fill属性,css column-fill属性怎么用

css column-gap属性定义及用法在css中&#xff0c;column-gap属性通常和columns、column-count等分列属性一起使用&#xff0c;用来设置元素内容分列(多列布局)后列与列之间的距离css column-gap属性语法格式css语法&#xff1a;column-gap: length / normal;(例&#xff1a;co…

python的matplotlib风格_matplotlib 的几种风格 练习

〇、准备数据import numpy as npx np.linspace(0, 5, 10)y x ** 2一、matlab风格的API1.单图from pylab import *figure()plot(x, y, r)xlabel(x)ylabel(y)title(title)show()2.多子图subplot(1,2,1)plot(x, y, r--)subplot(1,2,2)plot(y, x, g*-);二、matplotlib面向对象风格…

[Leetcode] Anagrams 颠倒字母构成词

Given an array of strings, return all groups of strings that are anagrams. Note: All inputs will be in lower-case. 题意&#xff1a;anagrams的意思是回文构词法。回文构词法有一个特点&#xff1a;单词里的字母的种类和数目没有改变&#xff0c;只是改变了字母的排列顺…

gradle spring_用于Spring应用程序的Gradle原型

gradle spring我发布了Gradle原型&#xff0c;可用于基于Springframework创建Java / Groovy应用程序。 当然&#xff0c;它不是一个真正的原型&#xff0c;因为这样的创作是不可能的 。不过&#xff0c;你可以创建&#xff0c;编辑和部署应用服务器很少的步骤。 对于可部署的软…

css点击事件不做反应,纯css无js实现点击事件

已经阅读主要根据的技术点&#xff1a;标签为 input 元素定义标注(标记)。label 元素不会向用户呈现任何特殊效果。不过&#xff0c;它为鼠标用户改进了可用性。如果您在 label 元素内点击文本&#xff0c;就会触发此控件。就是说&#xff0c;当用户选择该标签时&#xff0c;浏…

Spring Integration Framework简介

我们非常了解Spring框架和JMS 。 在本文中&#xff0c;我们将介绍称为Spring Integration的企业集成框架 。 Spring Integration是一个开源企业集成框架&#xff0c;可增强Spring单独完成的功能。 Spring Integration构建在Spring的IoC之上&#xff0c;它抽象了消息源和目标&am…

网络营销广告投放策略

网络营销广告投放策略 网络营销第一桶金&#xff1a;10年微博热火&#xff0c;粉丝1毛一个&#xff0c;我看到了这个机会。开发了注册微博账户的软件可以卖粉丝了怎么推广呢微博账户头像上加广告&#xff0c;去关注活人&#xff0c;被关住的人&#xff0c;就能看到广告&#xf…

空间皮肤代码_OpenCV实现皮肤表面粗糙度3D显示

点击上方蓝字关注我们微信公众号&#xff1a;OpenCV学堂关注获取更多计算机视觉与深度学习知识问题分析与思路这个是最近有人问我的一个问题&#xff0c;想把一个拍好的皮肤图像&#xff0c;转换为3D粗糙度表面显示&#xff0c;既然是粗糙度表面显示&#xff0c;我想到的就是把…

windows修改时间服务器,在Windows中设置时间服务器 2012 R2

大家都知道, 时的服务是任何网络中最重要的组成部分, 任何系统, 在所有计算机上同步时钟是我们可以做的事情工作&#xff0c;也都成功同步的内部系统最少. 通常情况下&#xff0c;我们有一个网络时间服务器以从外部时钟获得的时间和内部提供.什么NTP服务器的默认地图, 在这种情…

shell脚本遍历分库分表数据

vim shell.sh 十库百表 for n in {1..10}doif [ $n ! 10 ]thenn0"${n}"fifor i in {00..99}domysql -h host${n} -P port -uusername -ppwd -D database -e SQL >> lognamedonedone 转载于:https://www.cnblogs.com/Jaxlinda/p/7079391.html

q版地图制作软件_Flash动画的图形元件实例-Q版人物侧面行走

对于刚入门者而言&#xff0c;学会了基本图形的绘制之后&#xff0c;如何应用软件的各种动画补间功能&#xff0c;制作出具有表现力的动画&#xff0c;就需要更进一阶的知识技能了&#xff1b;那么&#xff0c;设计制作一个卡通人物的行走效果&#xff0c;如何从没有头绪的任务…

绝地服务器维护7月5日,绝地求生正式服7月5日停机更新维护内容公告

我们将在北京时间7月5日(星期四) 上午10点 开始正式服的停机维护。- 维护开始时间&#xff1a;7月5日(星期四) 上午10点 (预计3小时)玩家们大家好&#xff0c;伴随PGI2018的临近&#xff0c;我们将向大家呈现以PGI为主题、全新风格的PUBG。我们将向玩家们提供丰富的活动和奖品&…

javafx2_JavaFX 2 GameTutorial第1部分

javafx2介绍 我相信大多数软件开发人员可能会在年轻人&#xff08;年轻人&#xff09;生活的某一时刻被迫创建游戏来帮助他们学习编程语言&#xff08;我知道我曾经做过&#xff09;。 以前&#xff0c;我的第一台计算机实际上是Franklin Ace 1000 &#xff0c;后来是Apple [] …

webstorm最新破解方法

方法来自 Rover12421 大神。 1.从官网下载WebStorm2016.1安装。 2.下载 破解补丁 并解压&#xff0c;记住路径 3.编辑WebStorm安装目录下 bin 文件夹中的 WebStorm.exe.vmoptions 与 WebStorm64.exe.vmoptions 文件&#xff0c; 在头部加上 -javaagent:D:\Program Files (x86)\…

python作者 google面试_如果Google面试让你用python写一个树的遍历程序

前几天忽然对python很感兴趣&#xff0c;学了几天也感觉它非常的简洁实用。打破了我这么长时间对java C# C 和vb的审美疲劳&#xff0c;让我眼前一亮。“就像读英文一样简单”这句话评价python说的很合理。我对python的好感很大部分是因为听说google很多程序用python&#xff0…

加载页面就触发ajax,AJAX post方法,有时会在页面加载时触发,有时不会

我对AJAX有一个奇怪的问题&#xff0c;我在页面加载时使用AJAX POST方法返回对象地图。我正在调试该过程&#xff0c;有时会调用该方法&#xff0c;并且Java Servlet有时会运行。我正确地包含了JS导入&#xff0c;其他jQuery调用正常工作。我试过不同的探险家。我使用的是GET方…

在Java 8中使用不带静态导入的Mockito

如何通过在基于Java 8的项目中删除静态导入来简化Mockito的使用。 基本原理 Mockito API基于&#xff08;BDD&#xff09;Mockito类中聚集的静态方法&#xff08;大部分&#xff09;&#xff0c;然后进行非常流畅的链接方法调用。 可以使用模拟/间谍/给定/然后/验证静态方法启…