Spring 执行器 returns 404 带 Spring 引导(war 项目)
Spring Actuator returns 404 with Spring Boot (war project)
我正在使用 Spring Boot 2.7.0(但我也尝试过 2.6.7 和 2.5)和 Java 17,我想将 actuator 添加到该项目。该项目被打包为 war,因为它仍在使用 JSP,我们在将其打包为 jar 时还没有开始工作。由于兼容性问题,它使用了非常旧的 spring-security 版本(4.2.18.RELEASE,仍在使用 XML 配置),但除此之外,依赖项应该是最新的.在其他项目中,我从未遇到过执行器的任何问题。无论如何,我已经将它添加到 pom.xml
文件中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
具有这些属性:
management.server.port=8081
management.endpoint.health.enabled=true
management.endpoint.health.show-details=always
management.endpoint.health.status.http-mapping.DOWN=200
management.endpoints.web.exposure.include=*
我们已将此设置添加到我们的 spring 安全 XML 配置中,以允许对执行器的所有调用:
<http pattern="/actuator/**" auto-config="true" use-expressions="true" create-session="stateless" disable-url-rewriting="true" security="none"/>
我们有(很多)自定义配置,但我能想到的相关部分是这样定义的:
@EnableRabbit
@EnableRetry
@SpringBootApplication
@EnableAsync
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan({"com.company.something", "com.company.another"})
@ImportResource(locations = {"classpath*:META-INF/spring/applicationContext*.xml", "classpath:spring/webflow-config.xml"})
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
}
和
@Configuration
public class WebappConfiguration implements WebMvcConfigurer {
@Bean
public TomcatServletWebServerFactory tomcatFactory() {
return new CustomTomcatServletWebServerFactory();
}
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainerCustomizer() {
return container -> {
container.addContextCustomizers(ctx -> ctx.setReloadable(false));
container.addConnectorCustomizers(con -> con.setMaxPostSize(5000000));
};
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/web-resources/**").addResourceLocations("classpath:/META-INF/web-resources/");
}
@Bean
public DispatcherServletRegistrationBean dispatcherServletRegistrationBean() {
DispatcherServlet servlet = new DispatcherServlet();
servlet.setApplicationContext(new AnnotationConfigWebApplicationContext());
return new DispatcherServletRegistrationBean(servlet, "/");
}
private static class CustomTomcatServletWebServerFactory extends TomcatServletWebServerFactory {
@Override
protected void postProcessContext(Context context) {
((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
context.setResources(new ExtractingRoot());
}
}
}
当我 运行 应用程序时,我收到此错误:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 2 of method servletEndpointRegistrar in org.springframework.boot.actuate.autoconfigure.endpoint.web.ServletEndpointManagementContextConfiguration$WebMvcServletEndpointManagementContextConfiguration required a single bean, but 2 were found:
- dispatcherServletRegistration: a programmatically registered singleton - dispatcherServletRegistrationBean: defined by method 'dispatcherServletRegistrationBean' in class path resource [com/company/WebappConfiguration.class]
这是我觉得很奇怪的第一件事。据我了解,Spring 似乎检测到两个 servletEndpointRegistrar
豆。如果我尝试删除 dispatcherServletRegistrationBean
我 运行 进入此错误:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method errorPageCustomizer in org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration required a bean of type 'org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath' that could not be found.
如果我改为将 @Primary
注释添加到 dispatcherServletRegistrationBean
:
@Primary
@Bean
public DispatcherServletRegistrationBean dispatcherServletRegistrationBean() {
DispatcherServlet servlet = new DispatcherServlet();
servlet.setApplicationContext(new AnnotationConfigWebApplicationContext());
return new DispatcherServletRegistrationBean(servlet, "/");
}
应用程序确实启动了。但是,如果我导航到 http://localhost:8081/actuator
,我得到的是:
<Map>
<timestamp>2022-05-24T06:38:58.914+00:00</timestamp>
<status>404</status>
<error>Not Found</error>
<message>No message available</message>
<path>/actuator</path>
</Map>
这可能是什么原因造成的,我该如何解决?
我设法通过将 DispatchServlet
创建为与 DispatcherServletRegistrationBean
分开的 bean 来解决这个问题:
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet() {
DispatcherServlet servlet = new DispatcherServlet();
servlet.setApplicationContext(new AnnotationConfigWebApplicationContext());
return servlet;
}
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {
return new DispatcherServletRegistrationBean(dispatcherServlet, "/");
}
我正在使用 Spring Boot 2.7.0(但我也尝试过 2.6.7 和 2.5)和 Java 17,我想将 actuator 添加到该项目。该项目被打包为 war,因为它仍在使用 JSP,我们在将其打包为 jar 时还没有开始工作。由于兼容性问题,它使用了非常旧的 spring-security 版本(4.2.18.RELEASE,仍在使用 XML 配置),但除此之外,依赖项应该是最新的.在其他项目中,我从未遇到过执行器的任何问题。无论如何,我已经将它添加到 pom.xml
文件中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
具有这些属性:
management.server.port=8081
management.endpoint.health.enabled=true
management.endpoint.health.show-details=always
management.endpoint.health.status.http-mapping.DOWN=200
management.endpoints.web.exposure.include=*
我们已将此设置添加到我们的 spring 安全 XML 配置中,以允许对执行器的所有调用:
<http pattern="/actuator/**" auto-config="true" use-expressions="true" create-session="stateless" disable-url-rewriting="true" security="none"/>
我们有(很多)自定义配置,但我能想到的相关部分是这样定义的:
@EnableRabbit
@EnableRetry
@SpringBootApplication
@EnableAsync
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan({"com.company.something", "com.company.another"})
@ImportResource(locations = {"classpath*:META-INF/spring/applicationContext*.xml", "classpath:spring/webflow-config.xml"})
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
}
和
@Configuration
public class WebappConfiguration implements WebMvcConfigurer {
@Bean
public TomcatServletWebServerFactory tomcatFactory() {
return new CustomTomcatServletWebServerFactory();
}
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainerCustomizer() {
return container -> {
container.addContextCustomizers(ctx -> ctx.setReloadable(false));
container.addConnectorCustomizers(con -> con.setMaxPostSize(5000000));
};
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/web-resources/**").addResourceLocations("classpath:/META-INF/web-resources/");
}
@Bean
public DispatcherServletRegistrationBean dispatcherServletRegistrationBean() {
DispatcherServlet servlet = new DispatcherServlet();
servlet.setApplicationContext(new AnnotationConfigWebApplicationContext());
return new DispatcherServletRegistrationBean(servlet, "/");
}
private static class CustomTomcatServletWebServerFactory extends TomcatServletWebServerFactory {
@Override
protected void postProcessContext(Context context) {
((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
context.setResources(new ExtractingRoot());
}
}
}
当我 运行 应用程序时,我收到此错误:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 2 of method servletEndpointRegistrar in org.springframework.boot.actuate.autoconfigure.endpoint.web.ServletEndpointManagementContextConfiguration$WebMvcServletEndpointManagementContextConfiguration required a single bean, but 2 were found:
- dispatcherServletRegistration: a programmatically registered singleton - dispatcherServletRegistrationBean: defined by method 'dispatcherServletRegistrationBean' in class path resource [com/company/WebappConfiguration.class]
这是我觉得很奇怪的第一件事。据我了解,Spring 似乎检测到两个 servletEndpointRegistrar
豆。如果我尝试删除 dispatcherServletRegistrationBean
我 运行 进入此错误:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method errorPageCustomizer in org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration required a bean of type 'org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath' that could not be found.
如果我改为将 @Primary
注释添加到 dispatcherServletRegistrationBean
:
@Primary
@Bean
public DispatcherServletRegistrationBean dispatcherServletRegistrationBean() {
DispatcherServlet servlet = new DispatcherServlet();
servlet.setApplicationContext(new AnnotationConfigWebApplicationContext());
return new DispatcherServletRegistrationBean(servlet, "/");
}
应用程序确实启动了。但是,如果我导航到 http://localhost:8081/actuator
,我得到的是:
<Map>
<timestamp>2022-05-24T06:38:58.914+00:00</timestamp>
<status>404</status>
<error>Not Found</error>
<message>No message available</message>
<path>/actuator</path>
</Map>
这可能是什么原因造成的,我该如何解决?
我设法通过将 DispatchServlet
创建为与 DispatcherServletRegistrationBean
分开的 bean 来解决这个问题:
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet() {
DispatcherServlet servlet = new DispatcherServlet();
servlet.setApplicationContext(new AnnotationConfigWebApplicationContext());
return servlet;
}
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {
return new DispatcherServletRegistrationBean(dispatcherServlet, "/");
}