WebServer加CXF在SpringMVC环境下的坑

发布于 2018-11-22  298 次阅读


1、需要导入包


<!-- webservice -->
<cxf.version>2.2.3</cxf.version> 放<properties>标签中
 
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>

2、web.xml配置


<!-- 添加cxf 的servlet -->
<servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/ws/*</url-pattern>
    </servlet-mapping>

3.拷贝cxf配置文件,spring-context-webservice.xml,cxf-config.xml


3.1、spring-context-webservice.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:cxf="http://cxf.apache.org/core"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.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">
 
    <import resource="cxf-config.xml"/>
</beans>

3.2、cxf-config.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:jaxws="http://cxf.apache.org/jaxws"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
    xsi:schemaLocation="http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
        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://cxf.apache.org/jaxrs
        http://cxf.apache.org/schemas/jaxrs.xsd">
 
    <import resource="classpath*:META-INF/cxf/cxf.xml" />
    <import resource="classpath*:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath*:META-INF/cxf/cxf-servlet.xml" />

4、新建包webservice和webserviceImp,拷贝service包和serviceImp包下的接口和类到目录下(记得改实现类继承的接口为webservice目录下的接口)


接口类添加注解@WebService

接口暴露方法添加@WebMethod

实现类添加注解@Component("ShApplyWebService")

@WebService(endpointInterface = "com.six.webService.ShApplyWebService", serviceName = "ShApply")//endpointInterface为包所在的地址,src/main/java之后的地址、serviceName

为对外发布的服务名

5、拷贝自定义工具类ContextUtils.java到项目中(包名自加)


import java.util.Enumeration;
import javax.servlet.ServletContext;
 
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
 
public class ContextUtils {
    public static WebApplicationContext getSpringMVCContext() {
        WebApplicationContext rootWac = ContextLoader.getCurrentWebApplicationContext();
        // 获取servletContext
        System.out.println(rootWac + "ddddd");
        ServletContext servletContext = rootWac.getServletContext();
        // 获取子容器,名字最后对应servlet名字
        // 1.查看spring容器中的对象名称
        String[] beannames = rootWac.getBeanDefinitionNames();
        for (String beanname : beannames) {
            System.out.println(beanname);
        }
 
        System.out.println(servletContext);
 
        // 2.查看servlet中容器列表
        Enumeration<String> servletnames = servletContext.getAttributeNames();
        while (servletnames.hasMoreElements()) {
            System.out.println(servletnames.nextElement());
        }
 
        WebApplicationContext springmvc = WebApplicationContextUtils.getWebApplicationContext(servletContext,
                "org.springframework.web.servlet.FrameworkServlet.CONTEXT.SpringMVC");
        // System.out.println(springmvc+"eee");
        // 此处SpringMVC应改为自己web.xml中的SpringMVC的名字
        return springmvc;
    }
 
}

6、访问地址:http://localhost:8080/项目名/ws/3.2xml文件中<jaxws:endpoint>标签中address值?wsdl


若出现以下内容且控制台没有错误则表示初步搭建成功

WebServer加CXF在SpringMVC环境下的坑

7、打开插件解压在任意位置


链接: https://pan.baidu.com/s/1IZzhDd0uxmpjTzcSlYhLoA提取码: 3rvi

打开文件夹下的bin文件夹Shift+鼠标右键==>在此处打开命令窗口、拖中其中wsdl2java到命令窗口中,空格wsdl2java -encoding utf-8 第六步正常打开的地址。例如:

WebServer加CXF在SpringMVC环境下的坑

完成后在bin目录下会生成一个文件夹。

8、新建普通的maven项目,pom文件中 引入 cxf需要jar包(第一步)


将第七步生成的文件夹拷贝至新生成的项目src/main/java目录下

将生成接口中方法上添加 @XmlType( namespace = "http://namespace.thats.not.the.same.as.the.generated")

9、在生成的webserviceimp文件夹下打开类,添加方法(仔细看注释)


public void clientsoap() throws Exception{
        // 创建WSDL的URL,注意不是服务地址
                URL url = new URL("第六步正常打开的地址");
 
                // 创建服务名称
                // 1.namespaceURI - 命名空间地址 (wsdl文档中的targetNamespace
                // targetNamespace="http://webserviceImp.gxa/")
                // 2.localPart - 服务视图名 (wsdl文档中服务名称,例如<wsdl:service name="studentws">)
                QName qname = new QName("打开第六步地址页面搜索targetNamespace等于的值","打开第六步地址页面搜索wsdl:service该标签后的name值");
 
                // 创建服务视图
                // 参数解释:
                // 1.wsdlDocumentLocation - wsdl地址
                // 2.serviceName - 服务名称
                Service service = Service.create(url, qname);
                // 获取服务实现类
                // 参数解释:serviceEndpointInterface - 服务端口(wsdl文档中服务端口的name属性,例如<wsdl:port
                // binding="tns:studentwsSoapBinding" name="StudentWebServiceImpPort">)
                ShApplyWebService applyWebService =
                service.getPort(ShApplyWebService.class);
                 //调用查询方法
                 List<com.six.webservice.ShApply> apply = applyWebService.selectGetAll();
                 System.out.println(apply.size());
    }

添加main方法实例化对象运行该方法。

10、如果能够正常获取到结果,恭喜你,如果提示错误,而服务器控制台显示空指针异常,那我借鉴来的解决方法应该有一点小帮助。


在原项目的serviceImp包下的实现类,使用注解方式实例化对象时会报错,因为自动扫描找不到对应的类,这个时候就需要使用刚刚提供的工具类。

@Override
public List<ShApply> selectGetAll() {
    List<ShApply> applys = null;
    try {
        shApplyDao = (ShApplyDao) ContextUtils.getSpringMVCContext().getBean("shApplyDao");// 对象名称,引号内对象名称应与扫描后生成的对象名称一致
        applys = shApplyDao.selectGetAll();// 调用方法
    } catch (Exception e) {
        System.out.println(e);
    }
 
    return applys;
}

如果此时还是不能获取到数据,可以先访问一下自己原项目再运行第九步建的类,至于为什么需要访问原项目,我的理解可能是没有启动Spring,欢迎有知道的大牛不吝赐教。(若还是不能访问,恕在下无能,暂无法解决)


再无夏秋