编辑:这个问题提出的问题在codebulb.ch的这篇文章中得到了很好的解释和证实,包括JSF @ViewScoped,CDI @ViewSCoped和Omnifaces 之间的一些比较@ViewScoped,以及JSF @ViewScoped"设计漏洞" 的明确声明:5月24日, 2015 Java EE 7 Bean范围比较了2的第2部分
编辑:2017-12-05用于这个问题的测试用例仍然非常有用,但原始帖子(和图像)中关于垃圾收集的结论是基于JVisualVM,我发现它们无效.请改用NetBeans Profiler!现在我正在从NetBeans配置,而不是JVisualVM连接到GlassFish /似鲭水狼牙鱼,在这里我感到场得到引用(甚至@PreDestroy称为后)仍持有中强制GC的OmniFaces ViewScoped完全一致的结果与试验应用sessionListeners型的com.sun.web.server.WebContainerListener内ContainerBase$ContainerBackgroundProcessor,他们不会GC.
众所周知,在JSF2.2中,对于使用@ViewScoped bean的页面,使用以下任何一种技术导航(或重新加载)将导致@ViewScoped bean在会话中"悬空"的实例它不会被垃圾收集,导致堆内存不断增长(只要GET引发):
使用h:链接获取新页面.
使用h:outputLink(或HTML A标记)获取新页面.
使用RELOAD命令或按钮在浏览器中重新加载页面.
使用键盘重新加载页面在浏览器URL上输入ENTER(也是GET).
相比之下,通过使用一个h:commandButton来传递JSF导航系统会导致@ViewScoped bean的发布,从而可以对其进行垃圾回收.
这是由(由BalusC)在JSF 2.1上解释的.ViewScopedBean @PreDestroy方法未被我的小型NetBeans示例项目/sf/answers/2128728101/在JSF2.2和Mojarra 2.2.9中调用和演示,其中项目说明了各种导航案例,可在此处下载.(编辑:2015-05-28:完整代码现在也可以在下面找到.)
[编辑:2016-11-13现在还有一个改进的测试网络应用程序,包含完整的说明,@ViewScoped并在GitHub上与OmniFaces 和结果表进行比较:https://github.com/webelcomau/JSFviewScopedNav]
我在这里重复一个index.html的图像,它总结了导航案例和堆内存的结果:

问:如何检测由GET导航引起的这种"悬挂/悬挂"@ViewScoped bean并将其删除,或以其他方式呈现垃圾收集?
请注意,我不会在会话结束时询问如何清理它们,我已经看到了各种解决方案,我正在寻找在会话期间清理它们的方法,以便在会话期间堆内存不会过度增长由于无意中的GET导航.
wrt 如何使用f:viewParam对GET请求执行操作?
<f:metadata>
<f:viewParam name="id" value="#{tInputBean.id}" />
<f:event type="preRenderView" listener="#{tInputBean.init}" />
</f:metadata>
Run Code Online (Sandbox Code Playgroud)
我很想知道a preRenderView f:event是否放在f:metadata中是否重要.我已经检查了Java EE6教程,Java Server Faces 2.0完整参考和Core JSF2,并且没有一个在f:metadata中有f:event的例子,但我在网上看到了很多像这样的例子.
JSF2 Compl.Ref说p.540
f:metadata标记封装了用于指定Facelet视图的元数据的元素集,因此必须是f:view标记的子元素,并且可能不会出现在模板中.从JSF2.0开始,此标记的唯一目的是封装f:viewParam标记.
在f:metadata中放置f:事件(通常用于支持f:viewParam)是否具有特殊含义,或者仅仅是为了帮助将它与视觉/逻辑上的f:viewParam一起分组?
以下3篇文章提供了如何使用中间日志记录助手的答案,并仍然让底层记录器从客户端的方法报告给该日志记录助手(而不是将日志助手方法报告为源):
但似乎只提供Log4j 1.2的答案,它提供了现在已经不存在的:
Category.log(String callerFQCN, Priority level, Object message, Throwable t).
Run Code Online (Sandbox Code Playgroud)
log4J 2.5 API中的Logger似乎没有明显的等价物.
任何人都可以提供与直接使用Log4J 2.x兼容的答案吗?
硒-2.37.0
Firefox 24.0(虽然也尝试过 Chrome)
Mac OS X 山狮 10.8.5
涉及 Windows、特定于 Windows 的自动化工具/库或 Mac OS X 以外的操作系统的解决方案是不可接受的答案
首先我要指出的是,Stackoverflow 上经常有人提出非常类似的问题,我已经检查了每个提供的答案,但没有一个适用于 CuteWebUI_Uploader_Resource AJAX 文件上传器,我将在下面详细说明。
我有一个包含数据和文件的企业 Java Web 应用程序,希望自动映射并上传该 Web 应用程序中选定的数据和文件子集(到)单独的 ASP.NET Web 应用程序,该应用程序使用 CuteWebUI 工具包和 CuteWebUI_Uploader_Resource来自可爱软件。
在撰写本文时,http://cutesoft.net服务器已关闭几天;谷歌搜索提供了一些 CuteSoft 论坛点击可能有助于解决此问题,但我目前无法访问它们。
与许多文件上传器一样,CuteWebUI AJAX 文件上传器有一个浏览按钮和一个上传按钮。
我希望能够直接上传到 CuteWebUI AJAX 文件上传器,而无需使用“浏览”按钮(并且无需使用 Mac OS X 上的“浏览”对话框玩任何花招,因为浏览器无法使用我希望上传的文件在本地文件系统上,而是存储在可通过 Java 访问 Java Web 应用程序的服务器上,尽管为了测试我可以将它们放在本地文件系统上,如下所示)。
我很高兴其他文件上传者已经多次回答了这个问题(请参阅本文末尾的详尽列表),并且通常描述为大多数文件上传者的解决方案的过程大致如下:
识别由浏览按钮填充的文件上传路径(有时隐藏)的输入字段。有时需要使用 JavascriptExecutor 取消隐藏它并确保它是一个文本字段,然后使用 sendKeys 填充它。
找到匹配的“提交”上传按钮并单击()。
这不适用于 CuteWebUI AJAX 文件上传器。
我所针对的系统确实有一个 INPUT 元素,从名称上看,它用于存储文件上传路径,但事实上,当我手动尝试它时(并使用 Firebug 和 Selenium IDE 检查它),它的值并未填充根本没有,而是出现一个全新的可上传文件临时表。
以下 HTML …
这个问题是从Mac生成的:JSF:为什么开发阶段的JSF Web应用程序并不总是能够捕获复合组件的变化?.如果我可以在这里回答这个问题,我会有一个蛮力的策略来解决其他报告的问题,但这个问题有一个独立的目的.
问:如何在运行的Web应用程序中以编程方式强制清除Facelets内存缓存(以便我可以创建从[Clear Facelets Cache]按钮调用的侦听器)?
我正在使用NetBeans8.1beta和Glassfish4.1,并在NetBeans项目的/ build/web上进行部署.
我有 2 个 POM 用于 2 个独立的多模块父级:
CorePOM/pom.xml
SpectPOM/pom.xml
Run Code Online (Sandbox Code Playgroud)
SpecPOM 的子级使用 CorePOM 的子级,但我不想使 SpecPOM 成为 CorePOM 的子级。
我正在使用<dependencyManagement>导入:
<dependencyManagement>
<dependencies>
<!-- Use import to sync versions with CorePOM -->
<dependency>
<groupId>com.example.multi</groupId>
<artifactId>CorePOM</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
问:是否有等效的导入策略,以便<pluginManagement>我可以同步插件的版本?
如果没有,如何避免在 CorePom 和 SpecPOM 中重复插件版本?
根据Glassfish3.1.1的Mojarra-2.1.3(随Netbeans7.1一起发布)
我有一个带有侦听器void reset()的@SessionScoped支持bean跟踪器.
以下在f:使用template.xhtml的所有XHTML页面的元数据中都可以正常工作,例如/block/view.xhtml,它也采用查询参数id:
<f:view>
<f:metadata>
<f:viewParam name="id" value="#{blockManager.id}"/>
<f:event type="preRenderView" listener="#{tracker.reset}"/>
</f:metadata>
</f:view>
<ui:composition template="/template.xhtml">
Run Code Online (Sandbox Code Playgroud)
正如所料,每当我加载(GET)或重新加载页面时,无论id查询参数是什么,都会调用#{tracker.reset}侦听器(如调试日志记录所示).
但是,必须在每个XHTML页面(其中有数百个)中包含f:事件是很繁琐的,我首先尝试将其放在我的template.xhtml的f:metadata中.但是当我做了一些奇怪的事情时.它只调用#{tracker.reset}一次,第一次加载/block/view.xhtml(无论id查询参数是什么),然后在我加载另一个具有不同viewId的页面之后再没有调用它,例如/actor/view.xhtml,或/block/list.xhtml或/index.html.
我使用template.xhtml中的#{facesContext.viewRoot.viewId}检查了viewId.从viewId的角度来看很清楚,查询参数id在区分使用不同id查询参数调用的不同block/view.xhtml?id = [id]页面时没有任何作用,viewId总是只是'/ block /view.xhtml".
在写这个stackoverflow发布期间,我发现了我的问题的解决方案:只需将f:event放在f:metadata.xhtml的元数据之外(我在template.xhtml中使用f:metadata来分组f:events ).这适用于template.xhtml:
<f:metadata>
..
</f:metadata>
<f:event type="preRenderView" listener="#{tracker.reset}"/>
<h:head>
Run Code Online (Sandbox Code Playgroud)
但我仍然有以下问题:
问:为什么我是否在模板中的f:元数据中放置f:事件会有所不同?
我问的原因是Stackoverflow上有很多例子,在template.xhtml中使用f:元数据,在f:元素模板中使用f:事件.
BalusC在何时使用f:viewAction/preRenderView与PostConstruct?:
在每个HTTP请求上调用preRenderView事件.
如果我在最终XHTML页面的f:元数据中有preRenderView f:事件,或者在模板的f:元数据之外,但不在f:元数据中,那么这似乎只是真实的(按预期工作)模板.
关于是否应该在f:模板的元数据中使用f:event,或者在模板中使用f:metadata,似乎存在一些争论.
JSF2完全参考(Burns和Schalk)p.540指出:
f:metadata标记封装了用于指定Facelets视图的元数据的元素集,因此必须是f:view标记的子元素,并且可能不会出现在模板中.从JSF2.0开始,此标记的唯一目的是封装f:viewParam标记.
但是有很多关于f的Stackoverflow的例子:在模板中使用的元数据,并且有很多f:在f:metadata中使用的事件的例子.这也在这里讨论:
BalusC在哪里帮助解释:
.. <f:event>并非严格要求放在<f:metadata>中.它可以附加到任何组件...当你有一堆<f:viewParam>并且希望挂钩<f:event>以在所有那些视图参数之后调用一个动作时,确实存在于<f:metadata>内的纯自我纪录目的已经设定好了...
但我上面的经验表明,在f:模板的元数据中放置和f:事件会产生稍微不同(奇怪)的行为.为什么?
我有一个JSF复合组件util_primefaces:inplace_name,它需要一个"管理器"支持bean,当编辑实体的'name'字段时(使用p:inplace)执行持久性更新:
<cc:interface>
<cc:attribute name="manager" type="com.example.web.AbstractManager" required="false" default="#{blockManager}"/>
<cc:attribute name="element" type="com.example.entity.Element" required="true"/>
<cc:attribute name="elid" required="true"/>
<cc:attribute name="update" required="false" default="@parent"/>
..
</cc:interface>
<cc:implementation>
..
<p:inplace id="#{cc.attrs.elid}" editor="true" emptyLabel="UNDEF" >
<p:ajax
event="save"
listener="#{cc.attrs.manager.onInplaceNameSaveEvent}"
process="@this #{cc.attrs.elid}-name"
update="#{cc.attrs.update}"
/>
<h:inputText id="#{cc.attrs.elid}-name" value="#{cc.attrs.element.name}"/>
..
Run Code Online (Sandbox Code Playgroud)
例如@ViewScoped @ManagedBean BlockManager最终扩展了一个AbstractManager,它有一个监听器方法:
public void onInplaceNameSaveEvent(AjaxBehaviorEvent ae).
Run Code Online (Sandbox Code Playgroud)
[ASIDE:这里描述了不寻常的"elid"属性的原因,它在这个问题中没有进一步的作用:Primefaces p:inplace:如何更优雅地传播实体合并的EL表达式 ]
当我调用复合组件传入一个显式的#{blockManager}(或AbstractManager的其他子类)时,它工作正常:
<util_primefaces:inplace_name
element="#{tenancy}"
elid="tenancy"
manager="#{blockManager}"
/>
Run Code Online (Sandbox Code Playgroud)
但是如果我没有传入#{blockManager},那么在执行inplace edit并保存时,我得到一个错误,即onInplaceNameSaveEvent(AjaxBehaviorEvent)方法未知:
<util_primefaces:inplace_name
element="#{tenancy}"
elid="tenancy"
/>
Run Code Online (Sandbox Code Playgroud)
错误是:
WARNING: Method not found: com.example.web.BlockManager@71396a88.onInplaceNameSaveEvent(javax.faces.event.AjaxBehaviorEvent)
javax.el.MethodNotFoundException: Method not found: com.example.web.BlockManager@71396a88.onInplaceNameSaveEvent(javax.faces.event.AjaxBehaviorEvent)
at com.sun.el.util.ReflectionUtil.getMethod(ReflectionUtil.java:155)
Run Code Online (Sandbox Code Playgroud)
问:为什么在复合组件属性中使用default ="#{blockManager}"未正确使用辅助bean?
jsf ×5
jsf-2 ×5
facelets ×2
java ×2
automation ×1
caching ×1
default ×1
events ×1
file-upload ×1
glassfish ×1
heap-memory ×1
import ×1
log4j ×1
logging ×1
maven ×1
parent-pom ×1
plugins ×1
pom.xml ×1
prerender ×1
selenium ×1
view-scope ×1