简体   繁体   中英

How do I autowire my webservices client in my WAR application (using Spring)?

I'm using Maven 3.0.3, CXF 2.7.15, and Spring 3.2.11.RELEASE. Using the JAX-WS Maven plugin, web service client classes are auto-generated (plugin code below) ...

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>wsimport</goal>
            </goals>
            <configuration>
                <wsdlDirectory>${basedir}/src/wsdl</wsdlDirectory>
                <sourceDestDir>${basedir}/src/main/java</sourceDestDir>
                <packageName>org.collegeboard.bsorg</packageName>
            </configuration>
        </execution>
    </executions>
 </plugin>

which include the below

package org.myproject.bsorg;

/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.1.3-b02-
 * Generated source version: 2.1
 * 
 */
@WebService(name = "OrganizationWebService", targetNamespace = "http://mainco.org/bsorg/")
@XmlSeeAlso({
    ObjectFactory.class
})
public interface OrganizationWebService {

Then I have my own service class, in which I try and reference the above through auto wiring …

package org.mainco.subco.myproject.service;

@Service("orgWsdlSvc")
public class OrgWsdlServiceImpl implements OrgWsdlService 
{
    @Autowired
    private OrganizationWebService m_ows;

When I deploy my WAR file, I get the error

09:20:17,846 ERROR [org.springframework.web.context.ContextLoader] (MSC service thread 1-14) Context initialization failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orgWsdlSvc': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.mainco.bsorg.OrganizationWebService org.mainco.subco.myproject.service.OrgWsdlServiceImpl.m_ows; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.mainco.bsorg.OrganizationWebService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:290) [spring-beans-3.2.11.RELEASE.jar:3.2.11.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1148) [spring-beans-3.2.11.RELEASE.jar:3.2.11.RELEASE]

But I'm confused about how to properly autowire things in my web.xml and accompanying context files. In my WEB-INF/web.xml, I have

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:/META-INF/spring/applicationContext-myproject.xml,
        classpath:/META-INF/spring/infrastructure.xml
    </param-value>
</context-param>
<context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>myproject.webapp</param-value>
</context-param>

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

In my WEB-INF/dispatcher-servlet.xml file I have

<!-- Enable annotation driven controllers, validation etc... -->
<mvc:annotation-driven />

<context:component-scan base-package="org.mainco" />

<!-- Define spring bean for use with this app. -->
<bean id="localPropertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>classpath:application.properties</value>
    </property>
</bean> 

<!-- Define application properties for use in Spring classes -->
<util:properties id="applicationProperties" location="classpath:application.properties" />

<tx:annotation-driven />

and in my “applicationContext-myproject.xml”, I have

<util:properties id="applicationProperties" location="classpath:application.properties" />
<util:properties id="coreProperties" location="classpath:core.properties" />

<context:component-scan base-package="org.mainco.subco" />
<context:component-scan base-package="org.mainco.bsorg" />

<bean id="sessionTimeoutInSeconds" class="java.lang.Long">
    <constructor-arg>
        <value>3600</value>
    </constructor-arg>
</bean>

<!-- Enable annotation driven controllers, validation etc... -->
<mvc:annotation-driven />

    <!-- Define spring bean for use with this app. -->
    <bean id="localPropertyConfigurer"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location">
                    <value>classpath:application.properties</value>
            </property>
    </bean>

    <bean id="assert" class="org.mainco.subco.util.Assert" factory-method="createInstance" />

    <http-conf:conduit name="https://.*">
            <http-conf:tlsClientParameters secureSocketProtocol="TLSv1" disableCNCheck="true">
                    <sec:trustManagers>
                        <sec:keyStore type="JKS" password="${key.store.password}" resource="${key.store.file}" />
                    </sec:trustManagers>
                    <sec:keyManagers keyPassword="${key.manager.password}">
                        <sec:keyStore type="pkcs12" password="${private.key.password}" resource="${private.key.file}" />
                    </sec:keyManagers>
            </http-conf:tlsClientParameters>
    </http-conf:conduit>

<jaxws:client id="orgWebServiceClient"
    serviceClass="org.mainco.bsorg.OrganizationWebService"
    address="${wsdl.url}"
    /> 

<bean id="organizationWebService" class="org.mainco.bsorg.OrganizationWebService"></bean>

What do I need to do so I can autowire my web services client?

Per the suggestion given, I added the bean definition to my application context (see above) file, but received the following error upon deplyohing the application: 根据给出的建议,我将bean定义添加到我的应用程序上下文(见上文)文件,但在deplyohing应用程序时收到以下错误:

Context initialization failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orgWsdlSvc': Injection of autowired dependencies failed; nested exception is 
org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.myproject.bsorg.OrganizationWebService org.mainco.subco.myproject.service.OrgWsdlServiceImpl.m_ows; 
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'organizationWebService' defined in class path resource [META-INF/spring/applicationContext-myproject-mvc.xml]: Instantiation of bean failed; 
nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.mainco.bsorg.OrganizationWebService]: Specified class is an interface

You are missing the bean definition in your applicationContext-myproject.xml .

   <!-- Definition for OrganizationWebService bean -->
   <bean id="organizationWebService" class="org.mainco.bsorg.OrganizationWebService"></bean>

See this for more examples: http://www.mkyong.com/spring/spring-auto-wiring-beans-with-autowired-annotation/

EDIT: You are making progress. Now spring is able to find the autowired candidate in the application context.

However, there is another problem, the candidate is an interface and spring is not able to instantiate it (neither does javac). So, you need to create a class to implement your interface and describe it in your application context (instead or describing an interface). So; you need to create a org.mainco.bsorg.OrganizationWebServiceImp class implementing org.mainco.bsorg.OrganizationWebService and change your application context to:

   <bean id="organizationWebService" class="org.mainco.bsorg.OrganizationWebServiceImp"></bean>

More info here: Could not instantiate bean class: Specified class is an interface

EDIT2: Look at https://jax-ws.java.net/2.2.1/docs/UsersGuide.html#3.1.2_Starting_from_a_WSDL_File

The documentation clarifies that:

  1. Generate a service endpoint interface.

  2. Implement the service endpoint interface.

  3. Create a WAR file to deploy.

You need to implement the service endpoint interface with a concrete class eg: OrganizationWebServiceImp

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM