如何在带有嵌入式 tomcat 的 Spring Boot 应用程序中运行 hawt.io

Posted

技术标签:

【中文标题】如何在带有嵌入式 tomcat 的 Spring Boot 应用程序中运行 hawt.io【英文标题】:How to run hawt.io in spring boot application with embedded tomcat 【发布时间】:2015-07-31 07:29:28 【问题描述】:

我想将 hawt.io 作为嵌入式组件添加到具有嵌入式 tomcat 服务器的 spring boot 'fat jar' 应用程序中。

我该怎么做? 如何部署 hawt.io 战争文件?

更新: 我添加了依赖项:

hawtio-web hawtio-core hawtio-plugin-mbean hawtio-springboot 到我的pom

当我现在启动应用程序并打开 url localhost:8080/hatio/index.html 时,我会看到登录页面。 由于我不知道用户名和密码,我添加了 hawtio.authenticationEnabled=false 到我的 application.properties

但是 - 现在我收到警告 ' WARN 3420 --- [nio-8080-exec-4] o.s.web.servlet.PageNotFound : 不支持请求方法 'POST' 后跟一个空指针异常。

参考:http://hawt.io/configuration/index.html

【问题讨论】:

【参考方案1】:

我遇到了完全相同的问题 - 这是我解决问题的方法。

我发现 spring-boot 不支持旧的 web.xml 配置,这是当 maven-war-plugin 在你自己的战争之上覆盖 hawtio-web 项目时得到的。 由此产生的战争既包含您的网络代码,也包含 hawtio-web 存档的内容。

见http://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html

所以我在 spring 开始了配置 servlet 和过滤器的过程。

首先在 pom.xml 中添加必要的依赖项

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>$spring-boot-version</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-actuator</artifactId>
        <version>$spring-boot-version</version>
    </dependency>
    <dependency>
        <groupId>io.hawt</groupId>
        <artifactId>hawtio-springboot</artifactId>
        <version>$hawtio.version</version>
    </dependency>
    <dependency>
        <groupId>io.hawt</groupId>
        <artifactId>hawtio-core</artifactId>
        <version>$hawtio.version</version>
    </dependency>
</dependencies>

我正在使用这些版本:

<hawtio.version>2.0.0</hawtio.version>
<spring-boot.version>1.2.3.RELEASE</spring-boot.version>

添加一个配置类来配置 servlet 和过滤器:

@Configuration
public class HawtioConfiguration extends WebMvcConfigurerAdapter 

    @Override
    public void addResourceHandlers(final ResourceHandlerRegistry registry) 
        registry.addResourceHandler("/hawtio/plugins/**").addResourceLocations("/app/", "classpath:/static/hawtio/app/");
        registry.addResourceHandler("/hawtio/**").addResourceLocations("/", "/app/", "classpath:/static/hawtio/",
                "classpath:/static/hawtio/app/");
    

    @Override
    public void addViewControllers(final ViewControllerRegistry registry) 
        registry.addViewController("/hawtio/plugin").setViewName("forward:/plugin");
        registry.addViewController("/hawtio/").setViewName("redirect:/hawtio/index.html");
    

    @Bean
    public ServletRegistrationBean userServlet() 
        return new ServletRegistrationBean(new UserServlet(), "/user/*", "/hawtio/user/*");
    

    @Bean
    public ServletRegistrationBean jolokiaproxy() 
        return new ServletRegistrationBean(new ProxyServlet(), "/hawtio/proxy/*");
    

    @Bean
    public ServletRegistrationBean kubeservice() 
        return new ServletRegistrationBean(new ServiceServlet(), "/hawtio/service/*");
    

    @Bean
    public ServletRegistrationBean kubepod() 
        return new ServletRegistrationBean(new PodServlet(), "/hawtio/pod/*");
    

    @Bean
    public ServletRegistrationBean fileupload() 
        return new ServletRegistrationBean(new UploadServlet(), "/hawtio/file-upload/*");
    

    @Bean
    public ServletRegistrationBean loginservlet() 
        return new ServletRegistrationBean(new LoginServlet(), "/hawtio/auth/login/*");
    

    @Bean
    public ServletRegistrationBean logoutservlet() 
        return new ServletRegistrationBean(new LogoutServlet(), "/hawtio/auth/logout/*");
    

    @Bean
    public ServletRegistrationBean keycloakservlet() 
        return new ServletRegistrationBean(new KeycloakServlet(), "/hawtio/keycloak/*");
    

    @Bean
    public ServletRegistrationBean exportcontextservlet() 
        return new ServletRegistrationBean(new ExportContextServlet(), "/hawtio/exportContext/*");
    

    @Bean
    public ServletRegistrationBean mavenSource() 
        return new ServletRegistrationBean(new JavaDocServlet(), "/hawtio/javadoc/*");
    

    @Bean
    public ServletRegistrationBean contextFormatter() 
        return new ServletRegistrationBean(new ContextFormatterServlet(), "/hawtio/contextFormatter/*");
    

    @Bean
    public ServletRegistrationBean gitServlet() 
        return new ServletRegistrationBean(new GitServlet(), "/hawtio/git/*");
    

    @Bean
    public ServletListenerRegistrationBean hawtioContextListener() 
        return new ServletListenerRegistrationBean<>(new HawtioContextListener());
    

    @Bean
    public ServletListenerRegistrationBean fileCleanerCleanup() 
        return new ServletListenerRegistrationBean<>(new FileCleanerCleanup());
    

    @Bean
    public FilterRegistrationBean redirectFilter() 
        final FilterRegistrationBean filter = new FilterRegistrationBean();
        filter.setFilter(new RedirectFilter());
        filter.setUrlPatterns(Collections.singletonList("/hawtio/*"));
        return filter;
    

    @Bean
    public FilterRegistrationBean sessionExpiryFilter() 
        final FilterRegistrationBean filter = new FilterRegistrationBean();
        filter.setFilter(new SessionExpiryFilter());
        filter.setUrlPatterns(Collections.singletonList("/hawtio/*"));
        return filter;
    

    @Bean
    public FilterRegistrationBean cacheFilter() 
        final FilterRegistrationBean filter = new FilterRegistrationBean();
        filter.setFilter(new CacheHeadersFilter());
        filter.setUrlPatterns(Collections.singletonList("/hawtio/*"));
        return filter;
    

    @Bean
    public FilterRegistrationBean CORSFilter() 
        final FilterRegistrationBean filter = new FilterRegistrationBean();
        filter.setFilter(new CORSFilter());
        filter.setUrlPatterns(Collections.singletonList("/hawtio/*"));
        return filter;
    

    @Bean
    public FilterRegistrationBean XFrameOptionsFilter() 
        final FilterRegistrationBean filter = new FilterRegistrationBean();
        filter.setFilter(new XFrameOptionsFilter());
        filter.setUrlPatterns(Collections.singletonList("/hawtio/*"));
        return filter;
    

    @Bean
    public FilterRegistrationBean AuthenticationFilter() 
        final FilterRegistrationBean filter = new FilterRegistrationBean();
        filter.setFilter(new AuthenticationFilter());
        filter.setUrlPatterns(Arrays.asList("/hawtio/auth/*", "/jolokia/*", "/hawtio/upload/*", "/hawtio/javadoc/*"));
        return filter;
    


我已经用 jetty 和 tomcat 测试了这个 - 它适用于两者。 我也将此作为补丁提交给 hawtio,但目前尚未发布。您可以自己编译 hawtio 并导入 HawtioConfiguration: https://github.com/hawtio/hawtio/blob/master/hawtio-springboot/src/main/java/io/hawt/springboot/HawtioConfiguration.java

我还更新了 hawtio-sample 以使用 HawtioConfiguration: https://github.com/hawtio/hawtio/tree/master/hawtio-sample-springboot

现在我可以访问http://localhost:8080/hawtio/index.html访问hawtio

希望这会有所帮助。

祝你好运。

【讨论】:

对我来说很好,除了我评论了“/”的重定向,因为我的一些骆驼服务在通过 hawt.io 骆驼控制台导航后。 我对此进行了改进并将其添加为 hawtio 本身的功能。 github.com/hawtio/hawtio/pull/1969我不确定它会在哪个版本中。 更新了示例,现在它可以在刷新页面时工作,并且没有覆盖。添加了对我提交到 hawtio 的补丁的引用。 对这个设置的身份验证有任何想法吗?我已经设法让事情正常进行,但无法通过登录屏幕。我尝试将hawtio.authenticationEnabled=false 添加到属性文件中。 Hawt.io docs 提及 TomCat 的设置,但这是嵌入的。不确定tomcat-users.xml 是否适用。 使用java -Dhawtio.authenticationEnabled=false 运行确实允许我禁用登录屏幕,但仪表板左上角的图像链接损坏且导航无效。 Chrome 控制台显示大量 404。【参考方案2】:

这是我从最新教程中得到的(我猜 Hawtio 改进了这一点,因为这个问题最初是被问和回答的):使用 spring-boot-starter-parent 1.3.5.RELEASE,Hawtio 版本 1.4.64 ,包括以下依赖项:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>io.hawt</groupId>
            <artifactId>hawtio-springboot</artifactId>
            <version>$hawtio.version</version>
        </dependency>
        <dependency>
            <groupId>io.hawt</groupId>
            <artifactId>hawtio-core</artifactId>
            <version>$hawtio.version</version>
        </dependency>
        <dependency>
            <groupId>org.jolokia</groupId>
            <artifactId>jolokia-core</artifactId>
        </dependency>
    </dependencies>

下面是一个示例应用程序类,它设置了禁用身份验证的 Hawtio:

@SpringBootApplication
@EnableHawtio
public class SampleApplication 
    @Autowired
    private ServletContext servletContext;

    public static void main(String[] args) 
        System.setProperty(AuthenticationFilter.HAWTIO_AUTHENTICATION_ENABLED, "false");
        SpringApplication.run(SampleApplication.class, args);
    

    @PostConstruct
    public void init() 
        final ConfigManager configManager = new ConfigManager();
        configManager.init();
        servletContext.setAttribute("ConfigManager", configManager);
    

    /**
     * Set things up to be in offline mode
     * @return
     * @throws Exception
     */
    @Bean
    public ConfigFacade configFacade() throws Exception 
        ConfigFacade config = new ConfigFacade() 
            public boolean isOffline() 
                return true;
            
        ;
        config.init();
        return config;
    

您可以在包含 Apache Camel 的示例应用程序中找到完整代码:https://github.com/bowdoincollege/spring-boot-camel-sample

【讨论】:

以上是关于如何在带有嵌入式 tomcat 的 Spring Boot 应用程序中运行 hawt.io的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 中关闭嵌入式 Tomcat?

带有嵌入式 Tomcat 的 Jndi Mongodb Spring Boot,[重复]

带有嵌入式tomcat的Spring Boot +带有身份验证用户的访问日志

如何将简单的 Spring Boot(带有 Gradle 构建系统)部署到 Apache Tomcat(真实服务器,而不是嵌入服务器)?

使用带有嵌入式 Tomcat 的 Spring Boot Weblfux

带有嵌入式 Tomcat 的 Spring Boot 忽略了方法角色