H2控制台能否在Spring管理口运行?

问题描述 投票:0回答:1

使用 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 spring-boot h2 spring-boot-actuator
1个回答
1
投票

我试图复制你的问题,并找到了一个可能的解决方案。

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;
  }

}
© www.soinside.com 2019 - 2024. All rights reserved.