如何识别请求是否适用于javax.servlet.Filter
中的任何Spring Boot Actuator端点?
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
// Is req to any of Spring Actuator endpoint?
chain.doFilter(req, res);
}
我的想法是搜索invoker类或包(org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter),但我不确切知道如何。
这是应用程序日志的一部分。
EndpointHandlerMapping : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
EndpointHandlerMapping : Mapped "{[/env || /env.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping : Mapped "{[/archaius || /archaius.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping : Mapped "{[/health || /health.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,java.security.Principal)
EndpointHandlerMapping : Mapped "{[/features || /features.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping : Mapped "{[/prometheus || /prometheus.json],methods=[GET]}" onto public java.lang.Object io.micrometer.spring.autoconfigure.export.prometheus.PrometheusScrapeMvcEndpoint.invoke()
EndpointHandlerMapping : Mapped "{[/loggers || /loggers.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping : Mapped "{[/info || /info.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping : Mapped "{[/env],methods=[POST]}" onto public java.lang.Object org.springframework.cloud.context.environment.EnvironmentManagerMvcEndpoint.value(java.util.Map<java.lang.String, java.lang.String>)
EndpointHandlerMapping : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
EndpointHandlerMapping : Mapped "{[/refresh || /refresh.json],methods=[POST]}" onto public java.lang.Object org.springframework.cloud.endpoint.GenericPostableMvcEndpoint.invoke()
春季启动2:
似乎Spring Boot 2
的情况对于每个子版本都是不同的。以下代码主要是为了灵感,它必须针对特定的Spring Boot版本进行定制:
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
public class ActuatorEndpointFilter implements javax.servlet.Filter {
@Inject
private WebMvcEndpointHandlerMapping mvcepMapping;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HandlerExecutionChain handlerChain = mvcepMapping.getHandler((HttpServletRequest) request);
if (handlerChain != null) {
Object handler = handlerChain.getHandler();
// Following condition is enought in Spring Boot 2.1.1 and 2.1.2.
if (handler.getClass().getName().startsWith(
"org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping")) {
// IT IS ACTUATOR ENDPOINT in Spring 2.1.1 and 2.1.2!!!!
}
// Following conditions are mandatory in Spring Boot <= 2.1.0.RELEASE
if (handler instanceof HandlerMethod) {
Object bean = ((HandlerMethod) handler).getBean();
if (bean.getClass().getName().startsWith(
"org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping")) {
// IT IS ACTUATOR ENDPOINT in Spring 2.1.0!!!!
}
}
}
}
chain.doFilter(request, response);
}
}
我怀疑第一个条件,if (handlerChain != null)
,即:如果WebMvcEndpointHandlerMapping
返回一个处理程序,目前可能就任何Spring Boot 2版本都足够了,但我没有进一步调查它。
您可以将执行器上下文路径更改为/ management,以便所有请求都来到http://<host>:<port>/management/<here-come-your-endpoints>
在我们使用它的Spring Boot 1.5.3中,可以通过指定属性轻松完成:
management.context-path=/management
在application.properties文件中
这使得执行器易于跟踪,并且当涉及到网关暴露的内容时,可以实现灵活的配置。