cxf wsdl2java 生成的网络服务出现错误 "None of the policy alternatives can be satisfied"

error "None of the policy alternatives can be satisfied" with cxf wsdl2java generated webservice

我正在尝试基于 wsdl 文件构建 Web 服务客户端。此客户端用于使用 SpringMaven 构建的 java webapp。我使用 cxf 2.4.9 作为 eclipse 插件从 wsdl 文件生成 java 代码。 Web 服务需要用户名和密码才能使用,因此 wsdl 文件包含 usernameToken 策略.

当我测试生成的服务时,出现以下错误:

org.apache.cxf.ws.policy.PolicyException:可以满足 None 个备选政策。

以下是网络服务的代码片段:

wsdl 文件的策略部分:

<wsp:UsingPolicy wssutil:Required="true" />
<wsp:Policy wssutil:Id="policy">
    <ns0:SupportingTokens
        xmlns:ns0="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512">
        <wsp:Policy>
            <ns0:UsernameToken
                ns0:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512/IncludeToken/AlwaysToRecipient">
                <wsp:Policy>
                    <ns0:WssUsernameToken11 />
                </wsp:Policy>
            </ns0:UsernameToken>
        </wsp:Policy>
    </ns0:SupportingTokens>
</wsp:Policy>

生成的服务:

@WebServiceClient(name = "EURLexWebService", 
              wsdlLocation = "http://eur-lex.europa.eu/EURLexWebService?wsdl",
              targetNamespace = "http://eur-lex.europa.eu/search") 
public class EURLexWebService extends Service {

public final static URL WSDL_LOCATION;

public final static QName SERVICE = new QName("http://eur-lex.europa.eu/search", "EURLexWebService");
public final static QName EURLexWebServicePort = new QName("http://eur-lex.europa.eu/search", "EURLexWebServicePort");
static {
    URL url = null;
    try {
        url = new URL("http://eur-lex.europa.eu/EURLexWebService?wsdl");
    } catch (MalformedURLException e) {
        java.util.logging.Logger.getLogger(EURLexWebService.class.getName())
            .log(java.util.logging.Level.INFO, 
                 "Can not initialize the default wsdl from {0}", "http://eur-lex.europa.eu/EURLexWebService?wsdl");
    }
    WSDL_LOCATION = url;
}

public EURLexWebService(URL wsdlLocation) {
    super(wsdlLocation, SERVICE);
}

public EURLexWebService(URL wsdlLocation, QName serviceName) {
    super(wsdlLocation, serviceName);
}

...

}

用于调用网络服务的代码:

URL wsdlURL = EURLexWebService.WSDL_LOCATION;
File wsdlFile = getWsdlFile();
if (wsdlFile.exists()) {
     wsdlURL = wsdlFile.toURI().toURL();
}

EURLexWebService ss = new EURLexWebService(wsdlURL, EURLexWebService.SERVICE);
EURLexWebServiceProvider port = ss.getEURLexWebServicePort();

Map ctx = ((BindingProvider)port).getRequestContext();
ctx.put("ws-security.username", "mylogin");
ctx.put("ws-security.password", "mypassword");

doQuery(port);

最后是完整的堆栈跟踪:

org.apache.cxf.ws.policy.PolicyException: None of the policy alternatives can be satisfied.
at org.apache.cxf.ws.policy.EndpointPolicyImpl.chooseAlternative(EndpointPolicyImpl.java:165)
at org.apache.cxf.ws.policy.EndpointPolicyImpl.finalizeConfig(EndpointPolicyImpl.java:145)
at org.apache.cxf.ws.policy.EndpointPolicyImpl.initialize(EndpointPolicyImpl.java:141)
at org.apache.cxf.ws.policy.PolicyEngineImpl.createEndpointPolicyInfo(PolicyEngineImpl.java:555)
at org.apache.cxf.ws.policy.PolicyEngineImpl.getEndpointPolicy(PolicyEngineImpl.java:301)
at org.apache.cxf.ws.policy.PolicyEngineImpl.getClientEndpointPolicy(PolicyEngineImpl.java:283)
at org.apache.cxf.transport.http.policy.PolicyUtils.getClient(PolicyUtils.java:150)
at org.apache.cxf.transport.http.HTTPConduit.<init>(HTTPConduit.java:309)
at org.apache.cxf.transport.http.HTTPTransportFactory.getConduit(HTTPTransportFactory.java:248)
at org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:229)
at org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:236)
at org.apache.cxf.endpoint.AbstractConduitSelector.getSelectedConduit(AbstractConduitSelector.java:88)
at org.apache.cxf.endpoint.UpfrontConduitSelector.selectConduit(UpfrontConduitSelector.java:71)
at org.apache.cxf.endpoint.ClientImpl.getConduit(ClientImpl.java:842)
at com.mds.impco.el.webapp.controllers.HomeController.callEurlexWebService(HomeController.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:369)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:662)

我阅读了一些关于这个主题的主题。其中之一是代码片段,我将用户名和密码放在请求上下文映射中,但它不起作用。

我用 SoapUI 测试了 Web 服务,它工作正常,所以问题似乎出在我的 java 代码上...

任何帮助将不胜感激。

问题解决了!首先 wsdl 文件中有一个错误。

命名空间 http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512 不正确,必须替换为 http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702http://schemas.xmlsoap.org/ws/2005/07/securitypolicy

由于 wsdl 文件中定义了策略,因此填充 requestContext 映射是正确的做法。

最后,在 doQuery(EurlexWebServiceProvider port) 方法中,我构建了一个 SearchRequest 对象,它是 webservice 调用的参数,但我忘记设置该对象的 属性要求有效。