Spring MVC项目中CXF webservice @Autowired实战爬坑

项目环境:
Spring 4.2.3
apache cxf 3.1.11
jdk 7
tomcat 7

关键:
(1)导入正确的包
(2)application.xml,x-servlet.xml 和 web.xml

(1)导入正确的包

  • maven方式:注意国内目前可用的镜像有阿里云maven,其中的cxf版本比官网落后几个小版本。
<dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>apache-cxf</artifactId>
        <version>${国内镜像支持的版本号}</version>
        <type>pom</type>
  </dependency>
  • 官网下载jar包方式:http://cxf.apache.org/download.html

(2)application.xml,x-servlet.xml 和 web.xml

两个重点:

  1. 把controller相关的自动注解扫描配置在x-servlet,把其他类的注解扫描配置在application.xml。否则,会出现@Webservice类中使用@Autowired的实例为null的问题。
  2. 用@Webservice修饰接口,实现类继承这个接口。那么实现类不能用@Component、@Controller、@Service、@Repository等注释,但是可以在xml中配置bean的方式实现spring注入。这是个bug,目前4.2.3版本还存在这个bug。

具体代码:
application.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/websocket" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd ">
    <!-- # 目录: 1. 组件注解扫描,自动装配实例 2. cxf webservice注册 -->
    <context:component-scan base-package="cn.paic.rep.pare" >
    <!-- 仅仅在这个xml中扫描注入非Controller的类 -->
         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <bean id="riskMailWebserviceImpl" class="cn.paic.rep.pare.webservice.RiskMailWebserviceImpl"/>
    <jaxws:endpoint id="riskMailService" implementor="#riskMailWebserviceImpl" address="/sendRiskMail"/>
</beans>    

x-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd ">
    <!-- 注意:本xml的配置仅用于http请求的转发和返回,包括Controller返回值自动转字符串 -->
    <!-- # 目录: 1. 启用Controller相关的注解扫描 -->
    <context:component-scan base-package="cn.paic.rep.pare.controller" />
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>x</display-name>
  <context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>parisk.root</param-value>
  </context-param>
  <listener>
    <listener-class>
            org.springframework.web.util.Log4jConfigListener
        </listener-class>
  </listener>
  <context-param>
      <param-name>log4jConfigLocation</param-name>
      <param-value>classpath:log4j.properties</param-value>
  </context-param>
  <context-param>
    <param-name>log4jRefreshInterval</param-name>
    <param-value>6000</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
  </context-param>
  <context-param>
    <param-name>kmRootKey</param-name>
    <param-value>km.root</param-value>
  </context-param>
    <!-- 基于apache cxf实现的webservice -->
    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/ws/*</url-pattern>
    </servlet-mapping>
    <!-- 基于spring MVC实现的controller -->
    <servlet>
        <servlet-name>x</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>x</servlet-name>
        <url-pattern>/</url-pattern>
        <url-pattern></url-pattern>
    </servlet-mapping>
</web-app>

java类代码

package cn.paic.rep.pare.webservice;

import javax.jws.WebParam;
import javax.jws.WebService;

import cn.paic.rep.pare.util.DataWrapper;
@WebService  
public interface RiskMailWebservice {  

    String sendRiskMail(@WebParam(name = "text")String text);  

}  
package cn.paic.rep.pare.webservice;


import javax.jws.WebService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import cn.paic.rep.pare.service.mail.risk.RiskForecastMailSender;
import cn.paic.rep.pare.util.DataWrapper;

@WebService//这里不能加@Component等,必须在xml里用bean的方式注入
public class RiskMailWebserviceImpl implements RiskMailWebservice {  
    @Autowired
    @Qualifier("serviceA ")
    ServiceA serviceA ;
    @Autowired
    @Qualifier("serviceB ")
    ServiceB serviceB;

    public String doSth(String text) {
       //略
    }  
}  

测试类

package cn.paic.rep.pare.webservice;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

public class RiskMailWebserviceClient {

    public static void main(String[] args) {
        String address = "http://localhost:8080/${这里写你的项目名}/ws/sendRiskMail";
        JaxWsProxyFactoryBean jwpFactory = new JaxWsProxyFactoryBean();
        jwpFactory.setAddress(address);
        jwpFactory.setServiceClass(RiskMailWebservice.class);
        RiskMailWebservice helloWorld = (RiskMailWebservice) jwpFactory.create();
        System.out.println(helloWorld.doSth("12"));
    }
}

你可能感兴趣的:(spring,CXF)