关于Maven项目集成cxf框架发布和接收WebService
从网上找了很多,发现大多数都是类似“单机”版的发布,直到看了一篇博客,给我很大的启发。
在此感谢这位博客的作者:http://www.imooc.com/article/14635
下面我所写的适用于“单独发布WebService”也适用于“集成在项目中发布”。
如果单独发布WebService的话,就要用到文中的所有代码;
如果集成项目发布的话,则需要用到部分代码(详情请看我代码备注);
废话少说,开始…
1. 下载cxf相关jar
下载地址:http://cxf.apache.org/download.html
2. 配置环境变量
(其实也可以省略这一步,但是后续测试客户端调用时,需要用到dos命令,所以建议配置环境变量)
将下载的jar包压缩后会出现一个文件夹,进入到文件夹的bin目录,并复制当前目录的地址……不说了,因为它和jdk的环境变量配置一模一样(需要注意的是当前配置需要jdk1.6以上的版本支持)。
环境配置完之后,打开dos窗口,输入:wsdl2java -help(-help之前有个空格)
当出现以下内容时,则证明配置成功...

3. 编写项目的pom.xml
<properties>
<spring.version>4.3.3.RELEASE</spring.version>
</properties>
<dependencies>
<!-- 当前代码如果原pom.xml中存在的话可忽略 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.8</version>
</dependency>
<!--如果您是在项目中集成cxf的话,上面的那些maven相关jar在项目搭建时肯定是存在的,你只需要编写以下maven相关jar即可-->
<!--org.apache.cxf.transport.servlet.CXFServlet-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.8</version>
</dependency>
<!--不加这个包会报错Unable to locate spring NamespaceHandler for XML schema namespace [http://cxf.apache.org/jaxws]-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.8</version>
</dependency>
<!--java实现webservice,不部署到tomcat,需要jetty包支持-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.1.8</version>
</dependency>
</dependencies>
4.编写WebService的接口和实现类
package com.bjhg.cxf.service;
import javax.jws.WebMethod;
@javax.jws.WebService
public interface WebService {
@WebMethod//代表当前方法是被发布的,可忽略
public String getValue();
}
package com.bjhg.cxf.service.impl;
import javax.jws.WebService;
@WebService
public class WebServiceImpl implements com.bjhg.cxf.service.WebService{
@Override
public String getValue() {
return "德玛西亚";
}
}
上面代码中由于本人想把它的引用描述的详细些,所以有些注解和实现类写的是详细地址;
还有就是方法的参数可以根据自己的需求来编写,也可调用项目中其它接口的返回数据,由于上面代码是个示例,所以我返回的信息是“德玛西亚”(当然啦,你也可以返回“提莫队长,正在待命…”)
5.编写spring-web.xml和spring-webservice.xml
下面第一个代码块为spring-web.xml(也有的人喜欢叫spring-application.xml)
下面第二个代码块为spring-webservice.xml
如果您是在项目中集成cxf,那么您就忽略spring-web.xml(因为这个配置也是web项目必不可少的配置)
spring-webservice.xml主要是引用webservice接口的实现类,最终引入到web.xml中
第一个代码块:spring-web.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:context="http://www.springframework.org/schema/context"
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-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!--配置springmvc-->
<!--1.开启springmvc注解模式-->
<!--简化配置:
(1)主动注册DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter
(2)提供一系列功能:数据绑定,数字和日期的format @NumberFormt @DataTimeFormat,xml json默认的读写支持-->
<mvc:annotation-driven/>
<!--servlet-mapping-->
<!--2静态资源默认的servlet配置,(1)允许对静态资源的处理:js,gif (2)允许使用“/”做整体映射-->
<!-- 容器默认的DefaultServletHandler处理 所有静态内容与无RequestMapping处理的URL-->
<mvc:default-servlet-handler/>
<!--3:配置jsp 显示viewResolver-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 4自动扫描且只扫描@Controller -->
<context:component-scan base-package="com.bjhg.*.controller" />
<!-- 定义无需Controller的url<->view直接映射 -->
<mvc:view-controller path="/" view-name="redirect:/index"/>
</beans>
第二个代码块:spring-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:jaxws="http://cxf.apache.org/jaxws"
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"
default-lazy-init="true">
<!--发布webservice-->
<!-- implementor:是被发布webservice接口的实现类地址 -->
<!-- address:是项目发布成功后,浏览器中的访问地址 -->
<jaxws:endpoint implementor="com.bjhg.cxf.service.impl.WebServiceImpl" address="/ws"></jaxws:endpoint>
</beans>
这两个配置最后需要引入到项目中的web.xml的配置中
6.编写项目的web.xml
<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_2_5.xsd"
version="2.5">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 引入WebService的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-webservice.xml</param-value>
</context-param>
<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-web.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
如果您是在项目中集成cxf的话,上面的代码可以忽略,因为上面的servlet和过滤器的配置是一个web项目必然存在的,当然如果不存在,那您就加上,下面代码中监听器的配置,如果您的项目中存在的话也可以忽略
-
另外还得在科普一下(大神请忽略):
上面的代码中分别引入了两个两个配置文件,一个是引入spring-webservice.xml的配置,另一个是配置Servlet时引入的主配置文件spring-web.xml,请仔细观察,不要忽略。
-
我这项目的主配置文件叫spring-web.xml,也有很多人喜欢叫spring-application.xml,请注意。
-->
<!--Spring MVC是通过DispatcherServlet来加载Spring配置文件的,因此不需要在web.xml中配置ContextLoaderListener。
但是CXF却需要通过ContextLoaderListener来加载Spring。-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置CXF框架的核心Servlet -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<!-- 这个是servlet的初始化的优先级,写成2只因为不想跟上面的servlet冲突 -->
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<!--
这个是webservice浏览器访问时的地址,项目名后面加上server,后面的*号写webservice配置文件中的adress名
-->
<url-pattern>/server/*</url-pattern>
</servlet-mapping>
</web-app>
7.发布WebService
完成上面的配置之后,启动tomcat,在浏览器中输入:http:localhost:8080/项目名/server/ws?wsdl
解释一下,http:localhost:8080/项目名,这个就不用说了,后面的server是web.xml中配置cxf框架的核心Servlet那块的url-pattern,在后面的ws是spring-webservice.xml配置文件中的address,?wsdl这个就不用说了吧。
访问后出现下图类似的信息,则发布成功!
8.客户端访问WebService接口信息
客户端调用WebService的方法有很多种,在这里我采用的是用dos命令生成本地文件,之后进行调用。
由于开始的时候配置了cxf的环境变量,现在只需要打开dos窗口,输入:wsdl2java -d 客户端项目路径 -client http://localhost:8080/CxfService/server/ws?wsdl
示例:
解释一下:
1:wsdl2java,什么意思我也不知道,我就认为是人家的语法(就像你上网要遵循http协议,写java代码有java规范,生活在中国要遵守国家的法律一样,这个别钻牛角尖,就这样写)
2:-d,就是客户端项目的位置信息(如果不是maven架构的项目,写到src即可)
3:D:\appMng\aaa\src\main\java,就是客户端项目的本地地址信息了(我的项目叫aaa)
4:-client,webservice的暴露地址信息,也就是最后面的信息(上面第7步浏览器中的信息)
最后如果没报错,那就是成功了,刷新一下客户端访问的项目就会出来,webservice的本地文件。
如图:
接下来就编写main方法测试一下,数据是否调用成功:
上图中的web包就是我写的main方法测试类。
代码示例:
package com.bjhg.web;
import com.bjhg.cxf.service.WebService;
import com.bjhg.cxf.service.impl.WebServiceImplService;
public class Client {
public static void main(String[] args) {
// impl中的实现类
WebServiceImplService web=new WebServiceImplService();
// 调用生成的客户端类 WebService_WebServiceImplPort_Client。主要是_后面的name
WebService webServiceImplPort = web.getWebServiceImplPort();
// 此时通过webServiceImplPort可以调用到你接口信息中的方法
String value = webServiceImplPort.getValue();
// 最后打印输出
System.out.println(value);
}
}
截图:
最终,调用成功。
这块我得在多说一笔,由于我的接口信息写的很简单,只有一句“德玛西亚”,所有本地文件比较少。
正常来说,接口的返回数据可能会是对象信息,那么你要做的是:
①:返回对象的实体类要实例化(实体类名后面要implements java.io.Serializable)
②:webservice的实现类调用别处接口数据时,注解最好使用@Resource
③:客户端调用的话,需要遍历,遍历时最好使用增强for循环,如果调用数据中的某些数据,就直接.get就可以,如果需要遍历所有数据,需要在对应的实体类中加上toString();(此时的客户端本地文件会有对应的实体类文件,名字很容易区别)
④:如果生成的本地文件报错,并且报错的原因是关于WebService的,请注意,你的接口发布时webservice注解怎么写,生成的本地文件就怎样写。
最后,希望我写的这些能够对你们有所帮助。