Vaadin v23应用中如何正确处理POST/GET外部请求
Vaadin 23 接收外部POST请求(Google Drive推送通知场景)实现方案
现有两种尝试的问题根因
- 嵌套在MainView里的@WebServlet方案报错原因:
嵌套在View类内部的Servlet类不会被Servlet容器默认扫描注册,所有/notifications请求会被映射到/*的主VaadinServlet拦截,被当成前端路由请求查找对应视图,最终返回Could not navigate to 'notifications'错误。此外继承VaadinServlet处理非Vaadin逻辑本身就不合理,会走整套Vaadin请求处理链路,产生不必要的性能开销。 - Session级RequestHandler方案的缺陷:
这个方式虽然能在本地测试时生效,但不是标准实现。RequestHandler是和单个用户VaadinSession绑定的,必须先有用户访问Vaadin前端、建立有效Session后才会完成注册。Google Drive推送服务发请求时不会携带用户Session,生产环境大概率出现拦截失效的问题,同时Session级拦截器会处理该用户的所有Vaadin请求,额外增加性能损耗,不适合作为全局Webhook端点使用。
Vaadin 23 官方推荐的标准实现
Vaadin 23兼容Servlet 3.0+规范,处理脱离Vaadin生命周期的外部请求时,直接定义独立的标准Servlet即可,不需要和Vaadin的路由、Session逻辑绑定:
- 独立Servlet实现(适用于所有Vaadin 23部署形态)
不要把Servlet嵌套在View类内部,单独定义顶层Servlet类,配置好路径映射和异步支持即可:import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(value = "/notifications", asyncSupported = true) public class DriveNotificationServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { // 此处处理Google Drive推送逻辑:校验请求签名、读取请求头/请求体、投递到异步处理队列 resp.setStatus(HttpServletResponse.SC_OK); } } - Spring Boot集成场景简化实现
如果你的Vaadin 23是基于Spring Boot搭建的,直接用Spring的RestController定义端点更方便,不需要手动写Servlet:import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import jakarta.servlet.http.HttpServletResponse; @RestController @RequestMapping("/notifications") public class DriveNotificationController { @PostMapping public void handleNotification(HttpServletResponse response) { // 处理推送逻辑 response.setStatus(HttpServletResponse.SC_OK); } }
配置注意:如果遇到端点被Vaadin拦截的情况,直接在应用配置里调整Vaadin的拦截路径规则,把
/notifications排除出Vaadin的拦截范围即可,独立Servlet/Spring Controller的路径匹配优先级默认高于Vaadin主Servlet,大部分场景不需要额外配置。
Google Drive推送场景适配要点
- 端点不要依赖任何VaadinSession、UI上下文相关的逻辑,Google推送请求不会携带用户会话信息
- 必须开启异步支持,避免容器超时断开连接
- 收到推送后第一时间返回2xx响应,不要在请求线程里执行耗时操作,建议把通知内容投递到内部消息队列异步处理,避免触发Google的重试机制
内容的提问来源于stack exchange,提问作者Александр Хворостенко
相关产品推荐
相关产品推荐

