CXF 和弹簧启动执行器,执行器端点不可用

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

我有一个使用 Spring Boot 1.4.2 和 CXF JAXRS 的项目设置。我想将弹簧启动执行器添加到项目中。这是我添加到项目中的配置。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-actuator</artifactId>
</dependency>

在此之后我创建了一个 WAR 文件,然后将其部署在外部 tomcat 服务器中。但是当我访问健康 URL localhost:8080/management/health 时,它给出 404 HTTP 代码。服务器正常启动,我可以看到包含以下详细信息的日志:

健康配置日志

[localhost-startStop-1] 信息 org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping - 映射“{[/management/health || /management/health.json],products=[application/json]}" 公开 java.lang.Object

Servlet 配置日志

[localhost-startStop-1] 信息 org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean - 映射过滤器:'springSecurityFilterChain' 到:[/*]

[localhost-startStop-1] 信息 org.springframework.boot.web.servlet.FilterRegistrationBean - 映射 过滤器:“webRequestLoggingFilter”至:[/*]

[localhost-startStop-1] 信息 org.springframework.boot.web.servlet.FilterRegistrationBean - 映射 过滤器:“applicationContextIdFilter”至:[/*]

[localhost-startStop-1] 信息 org.springframework.boot.web.servlet.ServletRegistrationBean - 映射 servlet:'dispatcherServletRegistration' 到 []

[localhost-startStop-1] 信息 org.springframework.boot.web.servlet.ServletRegistrationBean - 映射 servlet:'dispatcherServlet' 到 [/]

[localhost-startStop-1] 信息 org.springframework.boot.web.servlet.ServletRegistrationBean - 映射 servlet:'CXFServlet' 到 [/services/*]

spring-boot cxf spring-boot-actuator
3个回答
1
投票

问题已解决,这是详细信息。由于 CXF 和 Spring Boot 一起配置在一起,因此 CXF REST API 和执行器端点都配置为 '/'。为 CXF RESt 端点配置的 servlet bean 的名称是dispatcherServletRegistration。由于 CXf 的引导启动器位于 POM 中,因此还发生了 CXF servlet 的自动配置。因此,您可以找到 CXFServlet 也配置为 /services/*。

将 servlet: 'dispatcherServletRegistration' 映射到 []

将 servlet: 'dispatcherServlet' 映射到 [/]

将 servlet:“CXFServlet”映射到 [/services/*]

我删除了自动配置选项(CXFServlet),因为我需要一些 CXF JAXRS 实现所需的自定义,并将 dispatcherServletRegistration 映射到 /services/*,现在一切正常。现在执行器在 '/' 下工作,CXF REST API 在 /services 下工作。


1
投票

就我而言,我有 Spring 1.5.X ,我无法对 CXF 和 Spring Actuator 使用两个不同的基本路径。我需要保留“/”作为根应用程序路径,并添加一个 RestEnpoint 来返回执行器运行状况结果。

因此,当 CXF 返回使用 @Autowired + ObjectMapper 在服务层上生成的 Health Info 的字符串结果时,我使用另一种方法。

注意:您应该启用注释上下文支持才能应用此解决方案。

以下解决方法对我有用:

将 CXF Servlet 保留在“/”上

在我的例子中,我使用 Camel + CXF,但是您需要做的就是创建以下组件来构建 Health 对象:

@Component
public class InfoHealthEndpoint extends HealthEndpoint {

    @Autowired
    private InfoEndpoint infoEndpoint;

    public InfoHealthEndpoint(HealthAggregator healthAggregator, Map<String, HealthIndicator> healthIndicators) {
        super(healthAggregator, healthIndicators);
    }

    @Override
    public Health invoke() {
        Health health = super.invoke();
        return new Health.Builder(health.getStatus(), health.getDetails())
                .withDetail("info", infoEndpoint.invoke())
                .build();
    }

}

并创建一个为 CXF 响应控制器返回字符串结果的服务。

@服务 公共课 HealthService {

@Autowired
private InfoHealthEndpoint infoHealthEndpoint;

@Autowired
private ObjectMapper mapper;

private static final String HEALTH_UP = "UP";

public void health(Exchange exchange) throws JsonProcessingException {

    Health health = infoHealthEndpoint.invoke();
    String healthReponse = mapper.writeValueAsString(infoHealthEndpoint.invoke());

    if(!HEALTH_UP.equals(health.getStatus().getCode())){
        Response response = Response.status(503).entity(healthReponse).build();
        exchange.getOut().setBody(response);
        exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);
    }else{
        exchange.getIn().setBody(healthReponse);
    }

}

}

注意:在我的例子中,我使用 Apache Camel (Exchange) 在路由上设置响应,但是此解决方案可以通过使用简单的字符串返回适用于另一种情况。

此答案归功于@Danny:将 Spring Boot Actuator /health 和 /info 合并为一个


0
投票

它对我有用

  @Bean
  @Primary
  public DispatcherServletPath dispatcherServletPath() {
    return () -> "";
  }
  
  @Bean
  public DispatcherServlet dispatcherServletActuator() {
    return new DispatcherServlet();
  }

  @Bean
  public ServletRegistrationBean<CXFServlet> dispatcherServlet() {
    ServletRegistrationBean<CXFServlet> cxf = new ServletRegistrationBean<>(new CXFServlet(), "/v1/*");
    cxf.setName("cxfServlet");
    return cxf;
    
  }
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.