Spring 使用执行器启动 Web 服务
Spring boot web services with actuator
我检查了其他几个类似的问题,但没有找到解决方案。
所以我有 spring 配置了 Web 服务的引导项目:
@Configuration
public class WebServiceConfig {
@Autowired
private Bus bus;
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, new ServiceImpl());
endpoint.publish("/ws");
return endpoint;
}
}
ServiceImpl,例如:
@javax.jws.WebService(serviceName = "ServiceImpl", portName = "ServiceImplPort", targetNamespace = "http://serivce.com/", endpointInterface = "pac.service...")
public class ServiceImpl...
服务工作正常。
我的那个实现的 POM 看起来像:
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-ws</artifactId>
<version>1.3.5.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.1.7</version>
</dependency>
...
主类:
@Configuration
@EnableAutoConfiguration
@EnableScheduling
@EnableWebMvc
@ComponentScan("com.package")
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
} }
到目前为止,一切正常 - WS 可以访问,但如果我添加到 POM:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
应用程序启动,我可以在日志中看到:
EndpointHandlerMapping:映射“{[/info
EndpointHandlerMapping:映射“{[/health
等等
还有:
ServerImpl: 将服务器的发布地址设置为 /ws
所以它开始时没有任何错误,看起来执行器应该可以工作,但是当我尝试调用执行器端点时,我收到 404 错误。
当我调用:localhost:8081/info
我得到:
没有找到服务。
我试过使用:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
但随后无法访问 WS(以及执行器端点)
有什么建议吗?
根据Spring Boot documentation "Customizing endpoints"
By default, all endpoints except for shutdown
are enabled. If you
prefer to specifically “opt-in” endpoint enablement you can use the
endpoints.enabled
property. For example, the following will disable
all endpoints except for info:
但可以肯定的是,您应该在 application.properties
中添加它,以便您可以使用 info
端点:
endpoints.enabled=true
endpoints.info.enabled=true
您已将 Spring Boot 的调度程序 servlet 映射到 /
,并将 CXF 的 servlet 映射到 /*
。这显示在您的应用程序的日志输出中:
2016-09-18 19:51:20.538 INFO 31932 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2016-09-18 19:51:20.540 INFO 31932 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'CXFServlet' to [/*]
这些映射发生冲突,CXF servlet 胜出。这意味着它将处理对您的应用程序发出的每个请求。例如,这会阻止 Spring Boot 的执行器处理对 /info
的请求。
您可以通过在 application.properties
中配置 cxf.path
将 CXF 移动到另一个路径来解决问题:
cxf.path=/cxf
这将相应地更改其 servlet 的映射:
2016-09-18 19:52:35.203 INFO 32213 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2016-09-18 19:52:35.205 INFO 32213 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'CXFServlet' to [/cxf/*]
您现在可以访问执行器的 /info
端点:
curl localhost:8080/info -i
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Application-Context: application
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 18 Sep 2016 18:57:08 GMT
{}
以及您基于 CXF 的服务的 WSDL:
$ curl http://localhost:8080/cxf/ws/Hello?WSDL -i
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Application-Context: application
Content-Type: text/xml;charset=UTF-8
Content-Length: 2286
Date: Sun, 18 Sep 2016 18:59:17 GMT
<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://service.ws.sample/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="HelloService" targetNamespace="http://service.ws.sample/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://service.ws.sample/" elementFormDefault="unqualified" targetNamespace="http://service.ws.sample/" version="1.0">
<xs:element name="sayHello" type="tns:sayHello"/>
<xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/>
<xs:complexType name="sayHello">
<xs:sequence>
<xs:element minOccurs="0" name="myname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHelloResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="sayHello">
<wsdl:part element="tns:sayHello" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="sayHelloResponse">
<wsdl:part element="tns:sayHelloResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="Hello">
<wsdl:operation name="sayHello">
<wsdl:input message="tns:sayHello" name="sayHello">
</wsdl:input>
<wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="HelloServiceSoapBinding" type="tns:Hello">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="sayHello">
<soap:operation soapAction="urn:SayHello" style="document"/>
<wsdl:input name="sayHello">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="sayHelloResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloService">
<wsdl:port binding="tns:HelloServiceSoapBinding" name="HelloPort">
<soap:address location="http://localhost:8080/cxf/ws/Hello"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
我检查了其他几个类似的问题,但没有找到解决方案。
所以我有 spring 配置了 Web 服务的引导项目:
@Configuration
public class WebServiceConfig {
@Autowired
private Bus bus;
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, new ServiceImpl());
endpoint.publish("/ws");
return endpoint;
}
}
ServiceImpl,例如:
@javax.jws.WebService(serviceName = "ServiceImpl", portName = "ServiceImplPort", targetNamespace = "http://serivce.com/", endpointInterface = "pac.service...")
public class ServiceImpl...
服务工作正常。
我的那个实现的 POM 看起来像:
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-ws</artifactId>
<version>1.3.5.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.1.7</version>
</dependency>
...
主类:
@Configuration
@EnableAutoConfiguration
@EnableScheduling
@EnableWebMvc
@ComponentScan("com.package")
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
} }
到目前为止,一切正常 - WS 可以访问,但如果我添加到 POM:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
应用程序启动,我可以在日志中看到:
EndpointHandlerMapping:映射“{[/info
EndpointHandlerMapping:映射“{[/health 等等
还有:
ServerImpl: 将服务器的发布地址设置为 /ws
所以它开始时没有任何错误,看起来执行器应该可以工作,但是当我尝试调用执行器端点时,我收到 404 错误。
当我调用:localhost:8081/info
我得到: 没有找到服务。
我试过使用:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
但随后无法访问 WS(以及执行器端点)
有什么建议吗?
根据Spring Boot documentation "Customizing endpoints"
By default, all endpoints except for
shutdown
are enabled. If you prefer to specifically “opt-in” endpoint enablement you can use theendpoints.enabled
property. For example, the following will disable all endpoints except for info:
但可以肯定的是,您应该在 application.properties
中添加它,以便您可以使用 info
端点:
endpoints.enabled=true
endpoints.info.enabled=true
您已将 Spring Boot 的调度程序 servlet 映射到 /
,并将 CXF 的 servlet 映射到 /*
。这显示在您的应用程序的日志输出中:
2016-09-18 19:51:20.538 INFO 31932 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2016-09-18 19:51:20.540 INFO 31932 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'CXFServlet' to [/*]
这些映射发生冲突,CXF servlet 胜出。这意味着它将处理对您的应用程序发出的每个请求。例如,这会阻止 Spring Boot 的执行器处理对 /info
的请求。
您可以通过在 application.properties
中配置 cxf.path
将 CXF 移动到另一个路径来解决问题:
cxf.path=/cxf
这将相应地更改其 servlet 的映射:
2016-09-18 19:52:35.203 INFO 32213 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2016-09-18 19:52:35.205 INFO 32213 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'CXFServlet' to [/cxf/*]
您现在可以访问执行器的 /info
端点:
curl localhost:8080/info -i
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Application-Context: application
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 18 Sep 2016 18:57:08 GMT
{}
以及您基于 CXF 的服务的 WSDL:
$ curl http://localhost:8080/cxf/ws/Hello?WSDL -i
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Application-Context: application
Content-Type: text/xml;charset=UTF-8
Content-Length: 2286
Date: Sun, 18 Sep 2016 18:59:17 GMT
<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://service.ws.sample/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="HelloService" targetNamespace="http://service.ws.sample/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://service.ws.sample/" elementFormDefault="unqualified" targetNamespace="http://service.ws.sample/" version="1.0">
<xs:element name="sayHello" type="tns:sayHello"/>
<xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/>
<xs:complexType name="sayHello">
<xs:sequence>
<xs:element minOccurs="0" name="myname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHelloResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="sayHello">
<wsdl:part element="tns:sayHello" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="sayHelloResponse">
<wsdl:part element="tns:sayHelloResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="Hello">
<wsdl:operation name="sayHello">
<wsdl:input message="tns:sayHello" name="sayHello">
</wsdl:input>
<wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="HelloServiceSoapBinding" type="tns:Hello">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="sayHello">
<soap:operation soapAction="urn:SayHello" style="document"/>
<wsdl:input name="sayHello">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="sayHelloResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloService">
<wsdl:port binding="tns:HelloServiceSoapBinding" name="HelloPort">
<soap:address location="http://localhost:8080/cxf/ws/Hello"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>