如何防止spring-boot Web应用程序在启动时接受http请求



我有一个前端有角度的spring-boot web应用程序。当我在web应用程序仍在启动时使用angular应用程序发送请求时,可能会出现web应用程序可以接受该请求并尝试处理该请求的情况。我相信应用程序能够在WebSecurityConfigurerAdapter扩展类初始化后立即接收请求。

当其他类还没有完全初始化时,这会导致问题。例如,当我试图注销一个在Web应用程序启动时仍在登录的用户时,它可能会导致SQLException,因为它还找不到数据库表user

在初始化最后一个类(用@SpringBootApplication注释的类(之前,我如何防止应用程序接受请求?

根据@Fullslack.dev的提示,我提出了以下解决方案。

@WebFilter(urlPatterns = {"/*"})
public class MyFilter implements Filter, ApplicationListener<ApplicationReadyEvent> {
private boolean webApplicationReadyToAcceptRequests = false;
@Override 
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
webApplicationReadyToAcceptRequests = true;
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
if(!webApplicationReadyToAcceptRequests) {
httpServletResponse.setHeader("Retry-After","35");
httpServletResponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "The server is currently starting up. Please try again in a moment.");
return;
}
else
filterChain.doFilter(servletRequest, servletResponse);
}
}
}

这是一个过滤器类,每个请求都必须首先通过,然后才能提交给@Controller和/或@Service注释类。如果变量webApplicationReadyToAcceptRequests仍然为false,则过滤器不会将请求传递到下游,而是会发送一条错误消息响应,其中包含httpstatus 503(服务不可用(。

确保你用以下内容注释了至少一个@Configuration配置类:

@ComponentScan(basePackages={ "FolderWhereMyFilterIsLocated"})

这将确保弹簧意识到过滤器的存在。

使用ApplicationReadyEvent的方法不够好,因为它在Spring web应用程序启动后传播,并且web服务器能够在那时接受请求:

Tomcat started on port(s): 4134 (http) with context path ''

应用程序已启动并运行:

http://localhost:4134/actuator/health返回{"status":"UP"}

如果在此之前需要进行一些初始化,则必须将其附加到spring上下文初始化,类似于对DB连接的初始化。最简单的方法是让你的";init";一些springbean的@PostConstruct方法中的代码。或者,还有一个老式的InitializingBean接口,在afterPropertiesSet()方法中具有类似的效果。

最新更新