You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OmniFaces @ViewScoped Bean离开页面时@PreDestroy方法未调用且报403错误

解决OmniFaces @ViewScoped @PreDestroy不触发的问题

核心原因

你遇到的403错误是Spring Security拦截了OmniFaces发送的卸载请求,而非HTTP协议的问题(sendBeacon在HTTP环境下完全可以正常工作)。标准JSF的javax.faces.view.ViewScoped本身不支持页面卸载时触发@PreDestroy,因为它的销毁逻辑依赖JSF视图的服务器端生命周期,用户主动离开页面时框架无法感知,所以只能依赖OmniFaces的实现。

解决步骤

1. 放行OmniFaces卸载请求路径

在Spring Security配置中,添加规则允许访问OmniFaces的卸载端点/omnifaces.unload(这是OmniFaces处理视图销毁请求的固定路径)。

如果使用Java配置:

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/omnifaces.unload").permitAll() // 放行卸载请求
                .anyRequest().authenticated();
        // 其他配置...
    }
}

如果使用XML配置:

<security:http>
    <security:intercept-url pattern="/omnifaces.unload" access="permitAll"/>
    <security:intercept-url pattern="/**" access="isAuthenticated()"/>
    <!-- 其他配置 -->
</security:http>

2. 确认OmniFaces配置正确性

确保项目中OmniFaces的jar包已正确引入,且使用@ViewScoped的页面已自动加载OmniFaces的unload脚本(OmniFaces会自动注入该脚本,无需手动引入)。

3. 验证请求状态

修改配置后重启应用,测试页面卸载场景:

  • 打开浏览器开发者工具的网络面板
  • 离开页面时,检查是否有POST请求到/omnifaces.unload且返回200状态码
  • 此时服务器控制台应输出Destroying view scoped desktop bean

额外说明

  • 标准JSF的javax.faces.view.ViewScoped无法实现页面卸载触发@PreDestroy,它的销毁时机仅为视图被JSF框架标记为过期(如会话超时、导航到其他视图且原视图被销毁),不覆盖用户主动关闭页面或跳转的场景。
  • 若问题仍存在,可检查OmniFaces版本与MyFaces的兼容性(你当前使用的OmniFaces 2.7.18和MyFaces 2.3.10是兼容的),或排查是否有其他过滤器拦截了请求。

内容的提问来源于stack exchange,提问作者scholt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 05:45:47