从WebSphere迁移到SpringBoot的JSF应用导航异常求助
解决方案:JSF迁移SpringBoot后的间歇性导航与ViewExpiredException问题
针对WebSphere迁移至SpringBoot(WAR转JAR)后出现的间歇性导航异常、Session ID变更及ViewExpiredException问题,可按以下步骤排查修复:
1. 调整Spring Security会话固定保护策略
异常日志显示ChangeSessionIdAuthenticationStrategy在变更Session ID,这会导致JSF视图状态绑定的旧Session失效,引发导航异常或ViewExpiredException。
- 若无需会话固定保护(或已通过其他方式防护),可禁用该策略:
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .sessionManagement() .sessionFixation() .none(); // 禁用会话固定保护 } }
- 若需保留会话固定保护,使用
migrateSession策略迁移Session属性,而非生成新Session ID:
http .sessionManagement() .sessionFixation() .migrateSession();
- 额外可排除JSF请求路径(如
*.xhtml)的会话固定保护:
http .sessionManagement() .sessionFixation() .migrateSession() .and() .authorizeRequests() .antMatchers("*.xhtml").permitAll();
2. 将JSF视图状态存储改为客户端模式
默认JSF视图状态存在HttpSession中,Session ID变更后会丢失视图状态导致ViewExpiredException。改为客户端存储可彻底规避此问题:
在SpringBoot的ServletContextInitializer中添加以下初始化参数:
@Override public void onStartup(ServletContext servletContext) throws ServletException { // 禁用服务器端视图状态存储,改用客户端 servletContext.setInitParameter("javax.faces.STATE_SAVING_METHOD", "client"); // 设置客户端视图状态超时时间(可选,单位秒) servletContext.setInitParameter("com.sun.faces.clientStateTimeout", "86400"); }
3. 移除com.sun.faces.enableRestoreView11Compatibility参数
该参数为JSF 1.1兼容开关,在JSF 2.2环境启用会破坏视图恢复逻辑,导致间歇性导航重载问题。移除后,结合客户端视图状态存储即可避免ViewExpiredException。
4. 统一Session作用域Bean的注解使用
将JSF原生@SessionScoped替换为Spring注解时,建议使用Spring的@SessionScope(而非@Scope("session")),确保Bean生命周期与Spring Session同步:
@Component("myBean") @SessionScope public class MyBean { // ... }
5. 检查PrimeFaces与Spring Security的兼容性
PrimeFaces 8.0的CSRF保护(默认启用)可能与Spring Security的CSRF过滤器冲突,导致请求被拦截引发页面重载。可:
- 禁用PrimeFaces CSRF保护:在初始化参数中添加
primefaces.CSRF_PROTECTION=false; - 确保Spring Security的CSRF令牌与PrimeFaces兼容,或统一使用Spring Security的CSRF防护。
内容的提问来源于stack exchange,提问作者Saka cocoX
相关产品推荐
相关产品推荐

