一、基于cxf框架,在spring框架中搭建webservice服务
步骤1,创建一个maven项目,首先导入spring相关依赖,再导入cxf依赖,配置tomcat插件等相关插件
<properties>
<spring.version>4.2.4.RELEASE</spring.version>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</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-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</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-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8080</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
2.写一个简单接口,功能描述是输入城市名称,返回当前城市天气情况,注解@WebParam(name="cityName")表示参数名
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface WeatherService {
public String getCityInfo(@WebParam(name="cityName")String cityName);
}
3.实现类
public class WeatherServiceImpl implements WeatherService {
@Override
public String getCityInfo(String cityName) {
String res = "";
if(cityName.equals("北京")) {
res = cityName+":大雨";
}
if(cityName.equals("上海")) {
res = cityName+":多云";
}
return res;
}
}
4.spring的配置文件做如下配置
<?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"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
">
<!-- 服务类,将服务类注入到spring容器 -->
<bean id="weather" class="com.enjoy.ws.WeatherServiceImpl"></bean>
<!-- 将服务发布 -->
<jaxws:server address="/weather">
<jaxws:serviceBean>
<ref bean="weather"/>
</jaxws:serviceBean>
</jaxws:server>
</beans>
5.web.xml做如下配置
<!--加载spring配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<!--配置监听-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置cxf的servlet-->
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
6.启动项目,run as —> maven build .输入tomcat7:run,通过配置的tomcat插件启动项目
浏览器输入 localhost:8080/ws/weather?wsdl
ip+端口+配置的tomcat插件的<path>标签的内容+web.xml配置的cxf的拦截路径+spring配置文件将服务发布的address的值+ ?wsdl
得到如下结果则证明发布成功
这里是关于发布服务的详细描述。
7.写一个main方法测试调用服务
需引入如下依赖
<dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>
import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
public class Weather {
public static void main(String[] args) throws Exception {
Service service = new Service();
Call call = service.createCall();
call.setTargetEndpointAddress("http://localhost:8080/ws/weather?wsdl");//服务地址
call.setOperationName(new QName("http://ws.enjoy.com/","getCityInfo"));
//参数设置,这里写cityName是服务端通过注解配置的,如果服务端不指定,需要写args0
call.addParameter("cityName",XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);// 设置返回类型
String res = (String) call.invoke(new Object[]{"北京"});
System.out.println(res);
}
}
得到结果,服务调用成功
二、springboot方式和xml方式本质上一样,下面对照上面步骤,做springboot方式的搭建。
1.创建maven项目,选择war包,引入依赖,注意选择parent的版本,这里有一个坑,下面具体说
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
2.写服务接口
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
@WebService
public interface WeatherService {
@WebMethod
@WebResult(name = "String")
public String getCityInfo(@WebParam(name="cityName")String cityName);
}
3.写接口实现类,这里的service注解是将这个实现类注入到spring容器中,也可以通过配置类将其注入
import org.springframework.stereotype.Service;
import com.enjoy.service.WeatherService;
@Service
public class WeatherServiceImpl implements WeatherService{
@Override
public String getCityInfo(String cityName) {
String res = "";
if(cityName.equals("北京")) {
res = cityName+":大雨";
}
if(cityName.equals("上海")) {
res = cityName+":多云";
}
return res;
}
}
4.配置类,配置cxf的拦截,配置WeatherServiceImpl服务路径
import javax.xml.ws.Endpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.enjoy.service.WeatherService;
@Configuration
public class WSConfig {
@Autowired
private WeatherService WeatherServiceImpl;
//这个相当于在web.xml中配置cxf的拦截配置
@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean(name="disServlet")
/*这里有一个坑,如果bean的name属性不指定,则默认引用方法名称dispatcherServlet,
在不同的springboot版本中效果不同,在2.0.3中可以正常启动,高版本会报错,
这是因为会覆盖掉默认的dispatcherServlet,所以这个注入的bean的名字不能用
dispatcherServlet,要不就在bean的name属性上指定,要么就将方法名换成别的
*/
public ServletRegistrationBean dispatcherServlet() {
return new ServletRegistrationBean(new CXFServlet(), "/ws/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public Endpoint endpoint() {
//指定weatherService服务的路径
EndpointImpl endpoint = new EndpointImpl(springBus(), WeatherServiceImpl);
endpoint.publish("/weather");
return endpoint;
}
5.写一个main方法启动项目
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WSWeatherApp {
public static void main(String[] args) {
SpringApplication.run(WSWeatherApp.class, args);
}
}
6.测试,浏览器输入localhost:8080/ws/weather?wsdl。
规则:ip+端口+配置的cxf拦截路径+服务类路径+?wsdl,由于springboot没有配置项目路径和端口,则默认没有项目路径和默认8080端口,想要修改则在配置文件中修改即可。
服务发布成功
用上面的测试main方法,填好参数,测试得到返回值
import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
public class Weather {
public static void main(String[] args) throws Exception {
Service service = new Service();
Call call = service.createCall();
call.setTargetEndpointAddress("http://localhost:8080/ws/weather?wsdl");//服务地址
String add2= "http://service.enjoy.com/";
call.setOperationName(new QName(add2,"getCityInfo"));
//参数设置
call.addParameter("cityName",XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.IN);
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);// 设置返回类型
String res = (String) call.invoke(new Object[]{"上海"});
System.out.println(res);
}
}