一.前言
出于学习的目的,将cxf与spring 在maven构建器下整合,构建过程中,出现了不少问题。
本文也将过程中碰到的问题一一列出了。废话少说,直接进入主题:
二.本例环境
maven3.3.9 + eclpise4.5.2 + spring3.2.17 + jdk1.8三.构建过程
1.编写服务端
1.1新建一Maven工程,CXFSpringWSServer:
Dynamic Web Model 2.5
java 1.8
jax-rs 2.0
jaxb 2.2
1.2在pom中,引入jar
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<spring.group>org.springframework</spring.group>
<spring.version>3.2.17.RELEASE</spring.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxws -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.7.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-transports-http -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.7.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxrs -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>2.7.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-core -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-core</artifactId>
<version>2.7.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-api -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-api</artifactId>
<version>2.7.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-core -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.xml.ws/jaxws-api -->
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.2.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.neethi/neethi -->
<dependency>
<groupId>org.apache.neethi</groupId>
<artifactId>neethi</artifactId>
<version>3.0.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ow2.spec.ee/ow2-jws-2.0-spec -->
<dependency>
<groupId>org.ow2.spec.ee</groupId>
<artifactId>ow2-jws-2.0-spec</artifactId>
<version>1.0.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- this jar has been after on spring-core or delete this jar-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-asm -->
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-asm</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>${spring.group}</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>${spring.group}.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>${spring.group}.ws</groupId>
<artifactId>spring-ws-security</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>${spring.group}.ws</groupId>
<artifactId>spring-xml</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/stax/stax-api -->
<dependency>
<groupId>stax</groupId>
<artifactId>stax-api</artifactId>
<version>1.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.woodstox/stax2-api -->
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>stax2-api</artifactId>
<version>3.1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.metro/webservices-api -->
<dependency>
<groupId>org.glassfish.metro</groupId>
<artifactId>webservices-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.metro/webservices-extra -->
<dependency>
<groupId>org.glassfish.metro</groupId>
<artifactId>webservices-extra</artifactId>
<version>2.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.geronimo.bundles/woodstox-core-asl -->
<!-- <dependency>
<groupId>org.apache.geronimo.bundles</groupId>
<artifactId>woodstox-core-asl</artifactId>
<version>4.1.2_1</version>
</dependency> -->
<!-- https://mvnrepository.com/artifact/org.codehaus.woodstox/woodstox-core-asl -->
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>woodstox-core-asl</artifactId>
<version>4.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/wsdl4j/wsdl4j -->
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
<version>1.6.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.ws.security/wss4j -->
<dependency>
<groupId>org.apache.ws.security</groupId>
<artifactId>wss4j</artifactId>
<version>1.6.19</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.ws.xmlschema/xmlschema-core -->
<dependency>
<groupId>org.apache.ws.xmlschema</groupId>
<artifactId>xmlschema-core</artifactId>
<version>2.2.1</version>
</dependency>
<build>
<finalName>CXFSpringWSServer</finalName>
<plugins>
<!-- <plugin> -->
<!-- <groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0-SNAPSHOT</version>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>tomcat7</server>
<username>admin</username>
<password>password</password>
<path>/CXFSpringWSServer</path>
<ignorePackaging>true</ignorePackaging>
</configuration>
</plugin> -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1-SNAPSHOT</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>tomcat7</server>
<path>/CXFSpringWSServer</path>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
1.3 在WEB-INF目录中新建web.xml文件,并将如下内容放于其中:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Archetype Created Web Application</display-name>
<!-- Spring 容器加载的配置文件 设置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:applicationContext-server.xml
</param-value>
</context-param>
<!-- Spring 配置 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- WebServices设置 -->
<servlet>
<servlet-name>CXFServices</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServices</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
这个配置文件是WEB应用的核心配置文件,如Listener的配置,servlet请求的映射等,这里并配置了启动的时候加载SPRING,并初使化我们的WEBSERVICE服务端配置文件。
1.4 增加服务端的JAVA类:
1.4.1 在src/main/java下创建包:
com.use.ws.entity
com.use.ws.server
1.4.2 创建实体类
package com.use.ws.entity;
public class User {
int id ;
String name = null;
String address = null;
String email = null;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
1.4.3定制客户端请求WebService所需要的接口
package com.use.ws.server;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import com.use.ws.entity.User;
@WebService
@SOAPBinding(style = Style.RPC)
public interface IService {
@WebMethod
User getUserByName(@WebParam(name = "name") String name);
void setUser(User user);
}
1.4.4 webservice暴露的方法实现
package com.use.ws.server;
import java.util.Date;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import com.use.ws.entity.User;
@WebService
@SOAPBinding(style = Style.RPC)
public class TestService implements IService {
@SuppressWarnings("deprecation")
public User getUserByName(String name) {
// TODO Auto-generated method stub
User user = new User();
user.setName(name);
user.setId((new Date()).getSeconds());
user.setAddress("china");
user.setEmail(name+"@test.com");
return user;
}
public void setUser(User user) {
// TODO Auto-generated method stub 测试用
System.out.println("############Server setUser###########");
System.out.println("user:"+user);
}
}
1.5 在src/main/resources 创建server端springBean:
<?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: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-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.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"/> -->
<bean id="userServiceBean" class="com.use.ws.server.TestService"/>
<bean id="inMessageInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean id="outLoggingInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<jaxws:server id="userService" serviceClass="com.use.ws.server.IService" address="/Users">
<jaxws:serviceBean>
<ref bean="userServiceBean"/>
</jaxws:serviceBean>
<jaxws:inInterceptors>
<ref bean="inMessageInterceptor"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="outLoggingInterceptor"/>
</jaxws:outInterceptors>
</jaxws:server>
</beans>
2 创建客户端测试调用类
2.1 独立的客户端请求类
创建包:package com.use.ws.client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.use.ws.entity.User;
import com.use.ws.server.IService;
public class TestClient {
public static void main(String[] args) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress("http://localhost:8080/CXFSpringWSServer/services/Users");
factory.setServiceClass(IService.class);
IService service = (IService) factory.create();
System.out.println("===============getUserByname============");
User user = service.getUserByName("zhuhl");
System.out.println(user);
System.out.println("user.name:" + user.getName() + " || user.address:" + user.getAddress() + " || user.email:"
+ user.getEmail());
System.out.println("===============setUser==================");
// user = new User();
user.setAddress("Shang Hai pudong LJZ ......");
service.setUser(user);
}
}
2.2 与SPRING的集成,首先需要在src下面建立配置文件applicationContext-client.xml,将输入以下内容
2.2.1创建client端springBean:
<?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"
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-3.2.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml"></import>
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<jaxws:client id="userWsClient" serviceClass="com.use.ws.server.IService" address="http://localhost:8080/CXFSpringWSServer/services/Users"/>
</beans>
2.2.2 创建java类
package com.use.ws.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.use.ws.entity.User;
import com.use.ws.server.IService;
public class SpringUsersWsClient {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-client.xml");
IService service = ctx.getBean("userWsClient", IService.class);
System.out.println("#############Client getUserByName##############");
User user = service.getUserByName("Zhuhl");
System.out.println(user);
user.setAddress("China-Shanghai");
service.setUser(user);
}
}
四.构建过程中遇到的问题:
1.环境问题:
1.1 Eclipse安装旧版插件启动报错问题:
Help -> Install New Software... -> Work with
-> 选择“The Eclipse Project Updates - http://download.eclipse.org/eclipse/updates/4.5”
-> 勾选"Eclipse Tests, Examples, and Extras" 下的 "Eclipse 2.0 Style Plugin Support"
上面的4.5是我的eclipse版本,改成你的eclipse版本即可.
1.2 右键eclipse的工程,选择属性,再选择Project Facets里面中选择Dynamic Web Module ,将3.0修改为2.5,可能会提示如下信息:
Cannot change version of project facet Dynamic Web Module to 2.5
找到 .setting文件夹内的org.eclipse.wst.common.project.facet.core.xml文件,文件格式大致如下:
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<runtime name="Apache Tomcat v5.5"/>
<fixed facet="jst.web"/>
<fixed facet="jst.java"/>
<installed facet="jst.java" version="5.0"/>
<installed facet="jst.web" version="2.5"/>
<installed facet="wst.jsdt.web" version="1.0"/>
</faceted-project>
直接手动修改jst.web对应的version即可。最后重启tomcatX就可以正常使用了。
1.3 web项目部署到Tomcat,启动后无法访问:
1.双击server面板中的Tomcat v7.0 Server,出现的Server Locations配置有三个选项:
选中Use Tomcat installation (take control of Tomcat Installation);
除此之外,此选项下面还有两个参数输入框:
-->Server path(即tomcat或者eclipse根目录)
-->Deploy path(工程文件的根目录,tomcat一般为webapps,workspace下一般为wtpwebapps)
2.在servers中新建的SERVER上右击——属性的General项下右边Location属性点击SwitchLocation按钮,设置成/Servers/Tomcat v7.0 Server at localhost.server
3.双击新建的server,修改Server Options设置:将Publish module contexts to separate XML files 打钩(最下面)
4. 配置WEB项目的server选项:右击WEB项目——属性(properties)——server(新建WEB项目后默认是none)选中里面您servers热部署中创建的server
2.jar包不整合问题:
2.1 spring-core-3.2.4与spring-asm-3.1.4冲突
删除spring-asm-3.1.4.jar或将spring-core-3.2.4.jar放在前面
2.2 woodstox-core-asl-4.4.1.jar与stax2-api-3.1.4.jar一样groupId应该都是 org.codehaus.woodstox而不是org.apache.geronimo.bundles
否则就报 Cannot create a secure XMLInputFactory错误!!