使用 Spring boot,带有执行器和内存中的 H2。
在application.properties中,我目前有(忽略不相关的设置):
server.port=8080
management.server.port=9090
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
按预期在 http://localhost:8080/h2-console 部署 h2 控制台。从文档中,似乎没有 h2.console.use-management-port 选项或 h2.console.port 选项。是否有可能将 h2 控制台设置为
http://localhost:9090/h2-console
或(最好)
http://localhost:9090/actuator/h2-console
我试图复制你的问题,并找到了一个可能的解决方案。
在
spring.h2.console.enabled
中将false
更改为application.properties
:
server.port=8080
management.server.port=9090
spring.h2.console.enabled=false
定义
ServletConfigurer
并在onStartup
中手动初始化H2控制台:
@Configuration
public class ServletConfigurer implements ServletContextInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class<?> webServlet = Class.forName("org.h2.server.web.WebServlet", true, classLoader);
Servlet servlet = (Servlet) webServlet.getDeclaredConstructor().newInstance();
ServletRegistration.Dynamic h2cs = servletContext.addServlet("h2-console", servlet);
h2cs.addMapping("/actuator/h2-console/*");
h2cs.setLoadOnStartup(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
包括
managementPort
到 tomcat 以运行 H2 控制台:
@Value("${management.server.port:${server.port}}")
private String managementPort;
@Bean
public ConfigurableServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
if (StringUtils.hasText(managementPort)) {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(Integer.valueOf(managementPort));
tomcat.addAdditionalTomcatConnectors(connector);
}
return tomcat;
}
使用过滤器从其他端口阻止
/actuator/**
:
@Configuration
@WebFilter(urlPatterns = { "/actuator/**" }, filterName = "actuatorFilter")
public class ActuatorFilter implements Filter {
@Value("${management.server.port:${server.port}}")
private Integer managementPort;
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain )throws IOException, ServletException {
if(request.getLocalPort() == managementPort){
filterChain.doFilter(request, response);
} else {
((HttpServletResponse) response).sendError(404);
}
}
}
我还没有找到直接使用管理端口作为连接器的方法,在我看来,后一部分更像是一种解决方法,而不是解决您问题的完美方法。我会尝试找到方法来改进我的答案的后半部分,或者其他一些用户可以提供更多见解。
希望对您有所帮助:)
编辑:
我发现我的
urlPatterns
里面的@WebFilter
不行,做了一些修改:
ActuatorFilter
:
@Component
public class ActuatorFilter implements Filter {
@Value("${management.server.port:${server.port}}")
private Integer managementPort;
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain )throws IOException, ServletException {
System.out.println("req: " + request);
if(request.getLocalPort() == managementPort){
filterChain.doFilter(request, response);
} else {
((HttpServletResponse) response).sendError(404);
}
}
}
FilterConf
:
@Component
public class FilterConf {
@Autowired
ActuatorFilter actuatorFilter;
@Bean
public FilterRegistrationBean filterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(actuatorFilter);
registration.addUrlPatterns("/actuator/*");
registration.setOrder(1);
return registration;
}
}