Vaadin实现所有页面前置过滤器的最优方案是什么
Vaadin 全局页面前置检查最优实现方案
针对页面访问前统一校验、不通过则跳转错误页的需求,Vaadin官方推荐优先使用原生路由拦截机制,也可以根据覆盖范围需求选择Servlet过滤器方案:
方案1:全局路由拦截器(优先推荐)
该方案完全适配Vaadin的单页应用路由逻辑,前端路由跳转、后端路由请求都会触发校验,不需要额外处理框架内部资源的排除逻辑,兼容性最好。
实现步骤:
- 注册全局
VaadinServiceInitListener,在所有UI初始化时添加页面进入前的拦截逻辑
// 非Spring Boot场景加@WebListener注解,Spring Boot场景直接注册为Bean即可 public class GlobalRouteCheckListener implements VaadinServiceInitListener { @Override public void serviceInit(ServiceInitEvent event) { event.getSource().addUIInitListener(uiInitEvent -> { // 给每个UI实例添加入口拦截器 uiInitEvent.getUI().addBeforeEnterListener(beforeEnterEvent -> { // 可跳过无需校验的公开页面,比如登录页、公开说明页 Class<?> targetPage = beforeEnterEvent.getNavigationTarget(); if (targetPage == LoginPage.class || targetPage == PublicNoticePage.class) { return; } // 执行自定义校验逻辑 boolean checkPassed = customCheckLogic(); if (!checkPassed) { // 方式一:跳转到自定义错误页面路由 beforeEnterEvent.rerouteTo(CustomErrorPage.class); // 方式二:直接返回指定HTTP错误码,使用Vaadin默认错误页 // beforeEnterEvent.rerouteToError(HttpServletResponse.SC_FORBIDDEN, "访问校验未通过"); } }); }); } }
- 自定义错误页示例(如果选跳转自定义页的方式)
@Route("custom-error") public class CustomErrorPage extends VerticalLayout { public CustomErrorPage() { setSizeFull(); setJustifyContentMode(JustifyContentMode.CENTER); setAlignItems(Alignment.CENTER); add(new H1("访问被拒绝"), new Paragraph("您的请求未通过安全校验,无法访问当前页面")); } }
方案2:Servlet过滤器(适配全站所有HTTP请求)
如果你的校验需要覆盖静态资源、非Vaadin路由的接口请求,可以使用Java标准的Servlet过滤器实现:
@WebFilter(urlPatterns = "/*") public class GlobalRequestCheckFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpReq = (HttpServletRequest) request; HttpServletResponse httpResp = (HttpServletResponse) response; String requestPath = httpReq.getRequestURI(); // 必须排除Vaadin内部资源路径,否则会导致框架功能异常 if (requestPath.startsWith("/VAADIN/") || requestPath.startsWith("/frontend/") || requestPath.startsWith("/sw.js") || requestPath.equals("/custom-error")) { chain.doFilter(request, response); return; } // 执行自定义校验逻辑 boolean checkPassed = customCheckLogic(); if (!checkPassed) { httpResp.sendRedirect(httpReq.getContextPath() + "/custom-error"); return; } chain.doFilter(request, response); } }
选型建议
- 仅需要校验Vaadin业务页面的场景,优先选方案1,实现更简单,没有漏检、误拦截的风险
- 需要覆盖静态资源、第三方接口等非Vaadin路由内容的场景,选择方案2
内容的提问来源于stack exchange,提问作者emad bahrami
相关产品推荐
相关产品推荐

