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

jsf教程

会话作用域跨越多个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 (名称=“ 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

jsf教程

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

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

相关文章

linux查询设备文件信息失败怎么办,Linux下使用blkid命令查询设备及文件系统信息的方法...

在Linux下可以使用blkid命令对查询设备上所采用文件系统类型进行查询。blkid主要用来对系统的块设备(包括交换分区)所使用的文件系统类型、LABEL、UUID等信息进行查询。要使用这个命令必须安装e2fsprogs软件包。直接使用blkid可列出当前系统中所以已挂载文件系统的类型。默认情…

linux rpm mysql mysql_config,Linux CentOS6 mysql rpm安装

选择操作系统及版本&#xff1a;点击5.6版本链接将下载好的文件上传至服务器下面开始安装&#xff1a;检查是是否有mysql的包# rpm -qa | grep -i mysql删除原有包# yum -y remove mysql-libs*开始安装下载好的三个文件&#xff1a;# rpm -ivh MySQL-server-5.6.38-1.el6.x86_6…

java 可视化_可视化Java 9模块关系

java 可视化正如我在之前的文章中所述 &#xff0c;我已经在Java 9 Jigsaw构建上运行Eclipse Neon了一段时间&#xff0c;并且没有任何问题。 我在周末花了几个小时来修改一些模块化工具的想法。 我为Eclipse Neon写了一个小插件&#xff0c;可视化了各个模块之间的连接。 现…

zybo的linux开发教程,Zybo全栈开发入门教程——连载三:创建Linux设备驱动和应用程序...

作者&#xff1a;Commanderfranz&#xff0c;编译&#xff1a; kenshin通过前面两篇文章我们不仅创建的自定义IP模块还移植了Linux操作系统&#xff0c;今天这篇文章的内容是将这两部分联系起来&#xff0c;其实我们创建的myLed IP相对于Linux操作系统可以是它的一个底层设备&a…

linux 二进制差分工具,打造Android万能的软件更新库

今日科技快讯阿里星球今天在苹果商店发布的更新动态显示&#xff0c;其将在近期停止APP内的音乐服务&#xff0c;用户可以通过新版本内的指引和说明&#xff0c;导出本地音乐。这意味着上线八个月后&#xff0c;阿里星球做出了一个重大决定&#xff1a;停止音乐服务后&#xff…

lambda 分类聚合_使用Java 8 Lambda,流和聚合

lambda 分类聚合总览 在本文中&#xff0c;我们将介绍使用Java 8 lambda&#xff0c;流和聚合来过滤和处理Collection中的对象。 这篇文章中的所有代码都可以在此处的 BitBucket中找到 。 对于此示例&#xff0c;我们将创建许多对象&#xff0c;这些对象代表我们IT基础架构中的…

linux镜像文件不要大于4g,Systemback制做大于4G的Ubuntu系统镜像

1 安装Systemback依此执行以下命令。sudo apt-get updatesudo add-apt-repository ppa:nemh/systembacksudo apt-get update && sudo apt-get install systemback unionfs-fuse安装完成&#xff1a;2 使用Systemback生成镜像文件输入管理员密码&#xff0c;打开后界面以…

黑马2016java_2016年成功的Java开发人员简介

黑马2016java2015年即将结束。 现在该总结过去一年中已完成的工作和未完成的工作。 此外&#xff0c;现在是预测下一个2016年的好时机。 您已经猜到这篇文章是关于2016年理想的Java开发人员的。 我想给你一个惊喜&#xff0c;这次我更改了预测的格​​式。 为了使预测更加客观…

spring一站式开发_Spring开发人员知道的一件事

spring一站式开发在最近的&#xff08;核心&#xff09;Spring框架培训课程中&#xff0c;有人问我&#xff1a;“&#xff08;Java&#xff09;Spring开发人员应该知道的一件事是什么&#xff1f;” 这个问题使我措手不及。 是的&#xff0c;&#xff08;核心&#xff09;Spri…

jax-ws和jax-rs_带有JAX-WS和Spring的Web服务应用程序

jax-ws和jax-rs1.简介 这是一个漫长的等待&#xff0c;但是我最终要发布有关使用Spring创建第一个基于SOAP的Web服务应用程序的教程。 JAX-WS &#xff08;用于XML Web服务的Java API&#xff09;是用于以XML格式创建Web服务的一组API&#xff0c;我们最常将其称为基于SOAP的We…

eclipse开发jsf_在Eclipse上创建JSF / CDI Maven项目

eclipse开发jsf当我在研究JSF和CDI示例时&#xff0c;我认为提到创建JSF和CDI Maven项目所需的步骤会很有用。 您可以找到以下步骤。 工具类 默认情况下&#xff0c;M2E插件随附的Eclipse Luna。 因此&#xff0c;无需自己安装插件。 WildFlye8.x。 从主菜单中选择文件->…

apache camel_Apache Camel的性能调整思路

apache camel时不时地&#xff0c;我会以Camel速度较慢的观点来询问有关优化Camel应用程序的问题。 骆驼只是连接不同系统的粘合剂&#xff0c;路由引擎全部在内存中&#xff0c;并且不需要任何持久状态。 因此&#xff0c;在99&#xff05;的情况下&#xff0c;性能问题是由于…

xmanager linux,教您用xmanager启动Linux上的图形界面程序-Go语言中文社区

对于习惯实体化的开发人员来说&#xff0c;还是界面化用着比较习惯&#xff0c;所以这就涉及到掌握使用Xmanager启动Linux上的图形界面程序&#xff0c;为了方便大家的使用&#xff0c;本集小编就详细的为大家讲解具体操作。具体步骤如下&#xff1a;1、首先下载Xmanager并安装…

android开发 文件分享到应用,Android 实现文件分享功能(共享多个文件)

效果如图&#xff1a;神一样的代码&#xff1a;针对image代码如下&#xff1a;IntentsharenewIntent(Intent.ACTION_SEND);share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));//此处一定要用Uri.fromFile(file),其中file为File类型&#xff0c;否则附件无法发送成功。s…

android 4.4.2截屏方法,android4.4.2 使用 uiautoviewer 截屏报错

1、正常启动后&#xff0c;使用 uiautomatorviewer 没有问题2、由于要使用 uiautomator&#xff0c;每次启动 uiautomator 服务后再使用 uiautomatorviewer 就会图片错误&#xff0c;启动 uiautomator 服务的步骤如下&#xff1a;1、Download jar files from uiautomator jsonr…

javaone_JavaOne 2015:为JDK 9做准备– blog @ CodeFX

javaoneJavaOne 2015看到了Project Jigsaw团队关于Java 9中的模块化的一系列讨论 。它们都是非常有趣的&#xff0c;并且充满了宝贵的信息&#xff0c;我敦促每个Java开发人员都注意它们。 除此之外&#xff0c;我想给社区一种搜索和引用它们的方法&#xff0c;因此我在这里总…

kafka spark_您在2016年会做什么? Apache Spark,Kafka,Drill等

kafka spark让我们玩得开心。 这是新的一年的开始-我们正处于新事物的门槛上-因此让我们期待您在2016年可能会做的事情。现在我知道做出预测的风险&#xff0c;尤其是有记录的预测&#xff0c;但是我很高兴您能在一年后回访&#xff0c;看看我对2016年的预测是如何完成的。 您…

android ini文件格式,ini是什么格式的文件?ini文件怎么操作?

类型&#xff1a;Android平台大小&#xff1a;622KB语言&#xff1a;中文 评分&#xff1a;5.0标签&#xff1a;立即下载ini文件主要存放用户所做的选择以及系统的各种参数。用户可以通过修改INI文件,来改变应用程序和系统的很多配置。自定义一个文件&#xff0c;会成一个deskt…

华为p6电信版 android 4.5,华为P6电信版系统应用apk补全教程 完整EMUI

现在要说的是华为P6电信版的系统应用apk补全教程&#xff0c;给你一个非阉割版的完整EMUI系统。大家应该都知道&#xff0c;电信定制版由于华为系统服务与电信的定制APP功能重叠&#xff0c;语音助手、云同步、云端备份、手机找回等系统应用apk全被“阉割”掉了&#xff0c;这几…

黑马ee在职进阶视频_进阶– Java EE 7前端5强

黑马ee在职进阶视频系列继续。 在初步概述和Arjan关于最重要的后端功能的文章之后 &#xff0c;我现在非常高兴让Ed Burns&#xff08; edburns &#xff09;使用他最喜欢的Java EE 7前端功能完成本系列。 感谢Markus Eisele让我有机会在他非常受欢迎的博客上发表帖子。 我和M…