Spring4 + cxf3 构建wsdl webservice

本文介绍通过spring4.0.2 + apache cxf3.0.3构建一个wsdl webservice服务。

项目的结构如下:

jaxws-client:客户端
jaxws-interface:公共接口
jaxws-server:服务端
说明:客户端与服务端均使用公共接口中的定义

1、新建一个maven项目jaxws-interface

其中pom.xml如下

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.hode</groupId>
	<artifactId>jaxws-interface</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	
	<properties>
		<spring.version>4.0.2.RELEASE</spring.version>
		<log4j.version>1.2.17</log4j.version>
		<cxf.version>3.0.2</cxf.version>
	</properties>
	
	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</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-tx</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>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>${log4j.version}</version>
		</dependency>
		
		<dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>
		
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        
	</dependencies>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>
	
</project>

编写一个接口UserService.java及一个对象类User.java,代码如下

package com.hode.ws.service;

import java.util.Date;

import javax.jws.WebService;

import com.hode.ws.mode.User;

@WebService
public interface UserService{

	public Date getDate();
	
	public User findUser(String name);
	
}

package com.hode.ws.mode;

import java.util.Date;

public class User{

	private String name;
	
	private int age;
	
	private double height;
	
	private Date birthday;

	public String getName(){
		return name;
	}

	public void setName(String name){
		this.name = name;
	}

	public int getAge(){
		return age;
	}

	public void setAge(int age){
		this.age = age;
	}

	public double getHeight(){
		return height;
	}

	public void setHeight(double height){
		this.height = height;
	}

	public Date getBirthday(){
		return birthday;
	}

	public void setBirthday(Date birthday){
		this.birthday = birthday;
	}

	@Override
	public String toString(){
		return "User [name=" + name + ", age=" + age + ", height=" + height + ", birthday=" + birthday + "]";
	}
	
}

interface层编写完毕。

2、新建一个服务端项目,此服务端使用jetty作为server

pom.xml如下,注意其中依赖了jaxws-interface,实际上服务端是实现了interface中定义的接口逻辑。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.hode</groupId>
	<artifactId>jaxws-server</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	
	<dependencies>
		<dependency>
			<groupId>com.hode</groupId>
			<artifactId>jaxws-interface</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.12</version>
		</dependency>
			
		<dependency>
			<groupId>org.eclipse.jetty</groupId>
			<artifactId>jetty-server</artifactId>
			<version>8.0.0.M3</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.eclipse.jetty</groupId>
			<artifactId>jetty-webapp</artifactId>
			<version>8.0.0.M3</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.eclipse.jetty</groupId>
			<artifactId>jetty-servlet</artifactId>
			<version>8.0.0.M3</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.eclipse.jetty</groupId>
			<artifactId>jetty-io</artifactId>
			<version>8.0.0.M3</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.eclipse.jetty</groupId>
			<artifactId>jetty-util</artifactId>
			<version>8.0.0.M3</version>
			<scope>provided</scope>
		</dependency>
		
		<dependency>
			<groupId>org.mortbay.jetty</groupId>
			<artifactId>jsp-2.1-glassfish</artifactId>
			<version>2.1.v20100127</version>
			<scope>provided</scope>
		</dependency>
		
	</dependencies>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
			
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<configuration>
					<version>3.0</version>
				</configuration>
			</plugin>
		</plugins>
	</build>
	
</project>

编写一个实现类,实现接口功能,定义为UserServiceImpl.java,代码如下

package com.hode.ws.service.impl;

import java.util.Date;

import com.hode.ws.mode.User;
import com.hode.ws.service.UserService;

public class UserServiceImpl implements UserService{

	@Override
	public Date getDate(){
		return new Date();
	}

	@Override
	public User findUser(String name){
		User u = new User();
		u.setAge(1);
		u.setBirthday(new Date());
		u.setHeight(12.1);
		u.setName("张三");
		return u;
	}

}


再编写spring配置文件applicationContext.xml,log4j.properties,JettyServer.java文件,代码依次如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	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-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd  
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
        http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
           
    <context:component-scan base-package="com.hode" />
    
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
	
	<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
	
	<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
	
	<cxf:bus>
		<cxf:inInterceptors>
			<ref bean="loggingInInterceptor" />
		</cxf:inInterceptors>
		<cxf:outInterceptors>
			<ref bean="loggingOutInterceptor" />
		</cxf:outInterceptors>
	</cxf:bus>
	
	<jaxws:server id="userService" address="/userService">
		<jaxws:serviceBean>
			<bean class="com.hode.ws.service.impl.UserServiceImpl" />
		</jaxws:serviceBean>
	</jaxws:server>
	
</beans>

log4j.rootLogger=INFO,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

log4j.logger.com.hode=DEBUG
package com.hode;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;


public class JettyServer {

	public static void main(String[] args) throws Exception{
		Server server = new Server(80);
		WebAppContext context = new WebAppContext();  
        context.setContextPath("/");  
        context.setWar("src/main/webapp");  
        server.setHandler(context);  
        server.start();  
        server.join();
	}

}

最后在目录webapp/WEB-INF中编写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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	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>jaxws-server</display-name>
	
	<servlet>
		<servlet-name>CXFService</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
		<init-param>
			<param-name>config-location</param-name>
			<param-value>classpath:applicationContext.xml</param-value>
		</init-param>
	</servlet>

	<servlet-mapping>
		<servlet-name>CXFService</servlet-name>
		<url-pattern>/ws/*</url-pattern>
	</servlet-mapping>
	
	
</web-app>

3、新建一个客户端项目,完成测试

编写pom.xml,可以看到client端同样是依赖了jaxws-interface项目,代码如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.hode</groupId>
	<artifactId>jaxws-client</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	
	<dependencies>
		<dependency>
			<groupId>com.hode</groupId>
			<artifactId>jaxws-interface</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.12</version>
		</dependency>
		
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>4.0.2.RELEASE</version>
			<scope>test</scope>
		</dependency>
		
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		
	</dependencies>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>
	
</project>

编写测试类进行测试,注意含BaseTest及JAXWSClientTest如下:

package com.hode;


import org.apache.log4j.Logger;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
public class BaseTest {

	protected Logger log = Logger.getLogger(getClass());
	
}



package com.hode;

import java.util.Date;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;

import com.hode.ws.mode.User;
import com.hode.ws.service.UserService;

@ContextConfiguration(locations={"classpath*:applicationContext.xml"})
public class JAXWSClientTest extends BaseTest {
	
	@Autowired
	private UserService userService;
	
	@Test
	public void getDate(){
		Date date = userService.getDate();
		log.info(date);
	}
	
	@Test
	public void findUser(){
		User user = userService.findUser("李四");
		log.info(user);
	}
	

}

再编写两个spring配置文件applicationContext.xml及log4j.properties文件

applicationContext.xml如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	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-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd  
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
        http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
	
	<context:component-scan base-package="com.hode" />
	
	<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
	
	<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
	
	<cxf:bus>
		<cxf:inInterceptors>
			<ref bean="loggingInInterceptor" />
		</cxf:inInterceptors>
		<cxf:outInterceptors>
			<ref bean="loggingOutInterceptor" />
		</cxf:outInterceptors>
	</cxf:bus>
        
    <jaxws:client id="userService" serviceClass="com.hode.ws.service.UserService" 
        address="http://localhost/ws/userService"/>
        
</beans>

log4j.properties文件可参考上面的写法。

4、完成编写后,执行测试

先运行JettyServer.java中的main方法,启动服务端,再运行测试类JAXWSClientTest截取部分日志如下

----------------------------
ID: 1
Address: http://localhost/ws/userService
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[197], content-type=[text/xml; charset=UTF-8], Host=[localhost], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 3.0.2]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:findUser xmlns:ns2="http://service.ws.hode.com/"><arg0>李四</arg0></ns2:findUser></soap:Body></soap:Envelope>
--------------------------------------
13333 [qtp2142734953-21] INFO  org.apache.cxf.services.UserServiceImplService.UserServiceImplPort.UserService  - Outbound Message
---------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:findUserResponse xmlns:ns2="http://service.ws.hode.com/"><return><age>1</age><birthday>2016-04-20T21:42:10.274+08:00</birthday><height>12.1</height><name>张三</name></return></ns2:findUserResponse></soap:Body></soap:Envelope>
--------------------------------------
13606 [qtp2142734953-22] INFO  org.apache.cxf.services.UserServiceImplService.UserServiceImplPort.UserService  - Inbound Message
----------------------------
ID: 2
Address: http://localhost/ws/userService
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[163], content-type=[text/xml; charset=UTF-8], Host=[localhost], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 3.0.2]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getDate xmlns:ns2="http://service.ws.hode.com/"/></soap:Body></soap:Envelope>
--------------------------------------
13625 [qtp2142734953-22] INFO  org.apache.cxf.services.UserServiceImplService.UserServiceImplPort.UserService  - Outbound Message
---------------------------
ID: 2
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getDateResponse xmlns:ns2="http://service.ws.hode.com/"><return>2016-04-20T21:42:10.760+08:00</return></ns2:getDateResponse></soap:Body></soap:Envelope>
--------------------------------------

Demo代码下载

结束。


赞赏(Donation)
微信(Wechat Pay)

donation-wechatpay