Java Camel 2.14.0/CXF 3.0.1 Jetty配置:协议不匹配错误
我们有两个web服务(REST+SOAP)在ApacheCamel 2.13.0中运行,它基于CXF版本2.7.10,一直使用SSL和基本身份验证,运行得非常好 由于Camel的版本升级到2.14.0版,该版本内部使用现在的CXF 3.0.1,我们的服务现在停止工作,因为端口x的Java Camel 2.14.0/CXF 3.0.1 Jetty配置:协议不匹配错误,java,jetty,cxf,apache-camel,Java,Jetty,Cxf,Apache Camel,我们有两个web服务(REST+SOAP)在ApacheCamel 2.13.0中运行,它基于CXF版本2.7.10,一直使用SSL和基本身份验证,运行得非常好 由于Camel的版本升级到2.14.0版,该版本内部使用现在的CXF 3.0.1,我们的服务现在停止工作,因为端口x的协议不匹配:引擎的协议是http,url协议是https-但是在版本更新期间,配置未被更改 ... Caused by: java.io.IOException: Protocol mismatch for port 8
协议不匹配:引擎的协议是http,url协议是https
-但是在版本更新期间,配置未被更改
...
Caused by: java.io.IOException: Protocol mismatch for port 8081: engine's protocol is http, the url protocol is https
at org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory.createJettyHTTPServerEngine(JettyHTTPServerEngineFactory.java:271)
at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.retrieveEngine(JettyHTTPDestination.java:121)
at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.finalizeConfig(JettyHTTPDestination.java:154)
... 48 more
因此,我创建了一个(只是一个简单的SOAP服务,有两个端点,都使用HTTP或HTTPS)
可以看到Jetty服务器的配置
实际服务被配置为bean,以便以后在Camel的路由中使用此bean:
@Bean(name="endpoint1ServiceSSL")
public CxfSpringEndpoint endpoint1ServiceSSL() throws Exception
{
final CxfSpringEndpoint factoryBean = new CxfSpringEndpoint();
factoryBean.setServiceClass(EnhancedEndpoint1Endpoint.class);
factoryBean.setWsdlURL("classpath:/wsdl/test.wsdl");
factoryBean.setEndpointName(new QName(NAMESPACE, "Endpoint1ServicePort", PREFIX));
factoryBean.setServiceName(new QName(NAMESPACE, "Endpoint1_Service", PREFIX));
factoryBean.setAddress(env.getProperty("services.address.ssl")+"/endpoint1");
factoryBean.setDataFormat(DataFormat.POJO);
final Map<String, Object> properties = new HashMap<>();
properties.put("schema-validation-enabled", "true");
properties.put("allowStreaming", true);
factoryBean.setProperties(properties);
factoryBean.getInInterceptors().add(new LoggingInInterceptor());
factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
return factoryBean;
}
以及其他与ssl密钥库相关的内容。请注意,CXF将在其初始化过程中使用jetty配置bean,因此为HTTPS调用的URL创建SSL安全连接——至少在版本升级之前是这样做的
该路由现在可以使用以下非常简单的路由访问服务:
public class Endpoint1Route extends RouteBuilder
{
@Override
public void configure() throws Exception
{
from("cxf:bean:endpoint1Service")
.to("log:endpoint1Service");
from("cxf:bean:endpoint1ServiceSSL")
.to("log:endpoint1ServiceSSL");
}
}
这在CXF 2.7.10和Camel 2.13.0中运行良好,但如上所述,升级后由于某种原因存在协议不匹配(希望从我链接的github项目中可以看出;克隆项目后,需要执行generate sources,然后作为Java独立应用程序启动ServicesApp
)
我还为版本升级创建了一个新分支,以简化两个版本之间的切换
有人知道为什么在版本升级之前工作的Jetty配置现在返回这个协议不匹配错误吗?我是否错过了任何我还没有弄清楚的更新库?还是我首先配置了一些错误的东西
@编辑: 在进一步测试之后,我现在确信CXF内部的一些API更改导致了问题,因为配置SSL安全Jetty服务器的bean在启动时不再执行,而在版本2.7.10中,bean将被执行 这将实际问题更改为“如何在Apache CXF 3.0.1中配置SSL安全的Jetty服务器”
@编辑#2: 我设法让一个SSL安全的Jetty服务器在Camel 2.14.0/CXF 3.0.1中运行,但仅通过。由于我们更喜欢Java配置而不是XML,因此我们仍在寻找一种在CXF 3.0.1中使用SSL配置Jetty的方法——不过,跳过JettyssEngineeFactory Springbean对我来说似乎是另一个CXF错误 为了澄清,在CXF 2.7.x中,可以在Java中配置jetty服务器,创建一个Springbean,返回一个
JettyHTTPServerEngineFactory
实例,如上面链接的github项目的主分支所示。CXF在配置服务器实例时使用了这个bean,因此设置了SSL安全的Jetty服务器。但是,在CXF 3.0.1中,不再调用此bean-仅调用JettyDestinationFactory
,我不知道如何使用它设置SSL安全服务器。另外,前面的XML示例没有提供关于如何使用目标工厂使用SSL设置Jetty的线索
由于文档中XML示例中的
引擎工厂
实际上映射到一个JettyHTTPServerEngineFactory
,并且XML上的Jetty配置工作正常,这似乎向我指出了CXF 3.0.1中的Spring bean注入错误。因为协议不匹配错误是由于CXF跳过jetty配置bean的bean初始化而导致的。然而,事实证明,通过CXF中的内部Spring版本更改,扩展Spring配置类会导致某些问题
在删除CxfEndpointConfig
中的扩展SoapSSLConfig
并使用@Import(SoapSSLConfig.class)
注入此配置类时,将执行bean初始化,因此Jetty服务器配置会像以前一样执行
过去的代码是:
@Configuration
@ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
public class CxfEndpointConfig extends SoapSSLConfig
{
...
}
这会导致注入失败。用下面的代码替换上面的代码解决了问题
@Configuration
@ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
@Import(SoapSSLConfig.class)
public class CxfEndpointConfig
{
...
}
@Configuration
@ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
@Import(SoapSSLConfig.class)
public class CxfEndpointConfig
{
...
}