WebService学习笔记
本学习贴是根据blog.java1234.com.cn的webservice视频教程整理和总结的,多处引用了Java1234_小锋老师的原文,感谢小峰老师的开源精神.致敬!!
前言
webservice是一种跨平台,跨语言的规范,用于不同平台,不同语言开发的应用之间的交互。
开发人员一般就是在具体平台开发webservice接口,以及调用webservice接口;每种开发语言都有自己的webservice实现框架。比如Java
就有 Apache Axis1
、Apache Axis2
、Codehaus XFire
、Apache CXF
、Apache Wink
、Jboss
RESTEasyd
等等...
第一节: 使用CXF开发WebService服务端接口
一.使用传统的jdk实现webservice功能
1.1 **新建maven project 填入项目名称 **
选择第一个 构建maven管理项目 而不是生成具体的java文件(只有目录)

使用的packeage为 jar (传统的project)

项目 结构如下:

本章节先展示如何使用javaee原生的jar开发webservice功能
1.2 更换j2ee的版本 使用maven生成的默认使用j2ee1.5 这里使用webservice功能需要使用1.7及以上

1.3 新建接口

1.4 编辑接口
package com.ztgeo.webservice;
import javax.jws.WebService;
@WebService //使用webservice进行声明类
public interface HelloWorld {
public String say(String str);
}
1.5 新建并编辑实现类

package com.ztgeo.webservice.impl;
import javax.jws.WebService;
import com.ztgeo.webservice.HelloWorld;
@WebService//同样适用webservice进行注解
public class HelloWorldImpl implements HelloWorld {
public String say(String str) {//接口发布后由对接方出入参数
return "对接方传过来的参数是:"+str;
}
}
1.6 编写主类service进行暴露接口(这里暂时在impl包中书写)
package com.ztgeo.webservice.impl;
import javax.xml.ws.Endpoint;
import com.ztgeo.webservice.HelloWorld;
public class Service {
public static void main(String[] args) {
System.out.println("webservice开始工作!!");
HelloWorld hl = new HelloWorldImpl();//1. 暴露的实现类
String address = "http://172.29.152.143/baolu"; //2. 暴露的地址 其中http必须 地址为本机地址 /后随便
Endpoint.publish(address, hl); //3.发布
System.out.println("webservice已经开始!!");
}
}
1.7 运行

1.8 访问
这里需要特别注意的是 需要使用url?wsdl访问 否则无法访问

WSDL的概述
这里的wsdl
是 Web Services Description Language
的缩写,是一个用来描述Web服务
和说明如何与Web服务通信
的XML
语言。WSDL是Web Service的描述语言
,用于描述Web Service的服务,接口绑定等,为用户提供详细的接口说明书。
二.使用cxf框架 实现webservice
2.1 pom.xml中添加和下载apache cxf框架 中央仓库
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.12</version>
</dependency>
2.2 这边使用jetty发布(类似于tomcat)web
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.1.12</version>
</dependency>
2.3 修改代码 使用cxf实现
package com.ztgeo.webservice.impl;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import com.ztgeo.webservice.HelloWorld;
public class Service {
public static void main(String[] args) {
System.out.println("webservice开始工作!!");
HelloWorld hl = new HelloWorldImpl();//1. 暴露的实现类
String address = "http://localhost/baolu"; //2. 暴露的地址 其中http必须 地址为本机地址 /后随便
//Endpoint.publish(address, hl); //3.发布
JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
factoryBean.setAddress(address);//设置发布地址
factoryBean.setServiceClass(HelloWorld.class);//设置接口类
factoryBean.setServiceBean(hl);//设置实现类
factoryBean.create();//启动
System.out.println("webservice已经开始!!");
}
}
2.4 请求页面 这里使用框架来构建 url无需加?wsdl也不会报错

第二章 使用cxf 开发客户端
客户端开发用来解析url
2.1 新建maven项目

使用wsdl2java
可以根据wsdl动态生成代码
这个工具在cxf的源码包中,点击xcf链接下载
下载后主要使用bin下的wsdl2java
命令工具

使用该命令前需要在系统变量中将该bin设置为系统变量.

2.2 使用wsdl2java
根据wsdl生成对应代码
cd 切换目录到项目文件夹
![]()
![]()
使用过程中 如果报指令不符合...确定加入环境变量后重开cmd
2.3 refresh ecilipse 查看生成的代码

暴露的节后生成类后依然是接口,具体的实现由HelloWorldService来实现
2.4 编写Client类,使用该接口 该类位于生成类的同包下
package com.ztgeo.webservice;
public class Client {
//客户端调用
public static void main(String[] args) {
HelloWorldService service = new HelloWorldService();//实体化服务类
HelloWorld hl = service.getHelloWorldPort();//获得接口类 (HelloWorld)
System.out.println(hl.say("你好,服务端!我是客户端")); //调用该接口的方法
}
}
2.5 结果展示

使用同样的操作可以解密贵公司提供的解密服务(c++编写)


第三章 使用CXF处理JavaBean以及复合类型
需求升级描述 由客户端传入字符串改为传入User类验证拥有的权限
3.1 服务端增加User类
重要字段:
private Integer id;//编号
private String usernamee;//用户名
private String password;//密码
3.2 服务端增加Role类
重要字段:
private Integer id;//编号
private String roleName;//角色名称
3.3 在暴露的接口(HelloWorld)体现需求 (过来用户 返回角色集合)
//给用户 返回角色集合
public List<Role> getRolesByUser(User user);
3.4 实现类中进行接口的实现
public List<Role> getRolesByUser(User user) {
List<Role> roles = new ArrayList<Role>();
if("wh".equals(user.getUsername())&&"123456".equals(user.getPassword())){
roles.add(new Role(1,"系统管理员"));
roles.add(new Role(2, "程序员"));
}else{
roles.add(new Role(3,"普通用户"));
}
return roles;
}
3.5 重新发布下

3.6 客户端使用wsdl2java
重新更新生成类(无需删除)

相应的实体类也生成了
3.7 更改客户端的调用
public static void main(String[] args) {
HelloWorldService service = new HelloWorldService();//实体化服务类
HelloWorld hl = service.getHelloWorldPort();//获得接口类 (HelloWorld)
//System.out.println(hl.say("你好,服务端!我是客户端")); //调用该接口的方法
User user = new User();//这里的user只能通过无参构造
user.setUsername("wh");
user.setPassword("123456");
List<Role> roles = hl.getRolesByUser(user);//调用实现
for (Role role : roles) {
System.out.println(role.getId()+"角色民称:"+role.getRoleName());
}
}
3.8 运行后输出

第四章 CXF 处理复杂类型(MAP)
问题暴露:
4.1 接口需求编写
public Map<String,List<Role>> getAllRoles();
4.2 方法的实现
public Map<String, List<Role>> getAllRoles() {
Map<String, List<Role>> roles = new HashMap<String, List<Role>>();
List<Role> roles1 = new ArrayList<Role>();
roles1.add(new Role(1,"角色一"));
roles1.add(new Role(2,"角色二"));
List<Role> roles2 = new ArrayList<Role>();
roles1.add(new Role(3,"角色三"));
roles.put("1",roles1);
roles.put("2",roles2);
return roles;
}
4.3 发布后发现问题

这时候需要特殊处理map类
4.4 暴露的接口中使用适配器进行处理
//返回所有用户角色和权限
@XmlJavaTypeAdapter(MapAdapte.class)//加入适配器类(不能处理的类的具体实现)
public Map<String,List<Role>> getAllRoles();
其中 具体来处理适配器的类是MapAdate 是自己需要编写的
4.5 编写适配器类的适配规则

//该类必须继承XmlAdapter 参数一 被转换的类型(数组 自行创建 map 已存在 )
public class MapAdapte extends XmlAdapter<MyRole[], Map<String, List<Role>>>{
}
其中MyRole自行创建 [] 代表多个类
4.6 创建 转换成的类 MyRole
主要属性:
private String key;
private List<Role> value;
其实就相当于 将key value转换成了具体的实体类 然后map转换成了实体类数组
4.7 实现继承需要被重写的方法
就是具体的转换过程
//适配转换 MyRole[]-->Map<String, List<Role>
@Override
public Map<String, List<Role>> unmarshal(MyRole[] v) throws Exception {
//实现的方式
Map<String, List<Role>> map = new HashMap<String, List<Role>>();
for (int i = 0; i < v.length; i++) {
map.put(v[i].getKey(), v[i].getValue());
}
return map;
}
//适配转换 Map<String, List<Role>-->MyRole[]
@Override
public MyRole[] marshal(Map<String, List<Role>> v) throws Exception {
MyRole[] myroles = new MyRole[v.size()];
int i =0;
for (String key : v.keySet()) {
//必须实例化 否则 空指针
myroles[i] = new MyRole();
myroles[i].setKey(key);
myroles[i].setValue(v.get(key));
i++;
}
return myroles;
}
4.8 再次发布运行

发布成功!!无报错
且真正的返回类型在wsdl中已有改变 为MyRole

4.9 客户端重新更新代码

4.10 客户端解析代码
public static void main(String[] args) {
HelloWorldService service = new HelloWorldService();//实体化服务类
HelloWorld hl = service.getHelloWorldPort();//获得接口类 (HelloWorld)
MyRoleArray myRoleArray = hl.getAllRoles();
//编译array
List<MyRole> roles = myRoleArray.getItem();
for (MyRole myRole : roles) {
//便利里面的角色名称
for (Role role : myRole.getValue()) {
System.out.println("角色id:"+role.getId()+"角色名称:"+role.getRoleName());
}
}
}
输出结果 :

第五章 CXF添加拦截器 (内置拦截器)
5.1 添加cxf内置in log拦截器(可以看到soap消息) __服务器端
factoryBean.getInInterceptors().add(new LoggingInInterceptor());//in日志拦截器 进入启用
5.2 添加cxf内置out log拦截器(可以看到soap消息) __服务器端
factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());//out日志拦截器 退出启用
5.3 服务器端启动-->客户端调用 查看日志
webservice开始工作!!
七月 11, 2017 9:00:49 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
信息: Creating Service {http://webservice.ztgeo.com/}HelloWorldService from class com.ztgeo.webservice.HelloWorld
七月 11, 2017 9:00:51 下午 org.apache.cxf.endpoint.ServerImpl initDestination
信息: Setting the server's publish address to be http://localhost:80/baolu
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
webservice已经开始!!
七月 11, 2017 9:00:58 下午 org.apache.cxf.services.HelloWorldService.HelloWorldPort.HelloWorld
信息: Inbound Message
----------------------------
ID: 1
Address: http://localhost/baolu?wsdl
Http-Method: GET
Content-Type:
Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Type=[null], Host=[localhost], Pragma=[no-cache], User-Agent=[Apache-CXF/3.1.12]}
--------------------------------------
七月 11, 2017 9:01:00 下午 org.apache.cxf.services.HelloWorldService.HelloWorldPort.HelloWorld
信息: Inbound Message
----------------------------
ID: 2
Address: http://localhost/baolu
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[168], content-type=[text/xml; charset=UTF-8], Host=[localhost], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache-CXF/3.1.12]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAllRoles xmlns:ns2="http://webservice.ztgeo.com/"/></soap:Body></soap:Envelope>
--------------------------------------
七月 11, 2017 9:01:00 下午 org.apache.cxf.services.HelloWorldService.HelloWorldPort.HelloWorld
信息: 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:getAllRolesResponse xmlns:ns2="http://webservice.ztgeo.com/"><return><item><key>1</key><value><id>1</id><roleName>角色一</roleName></value><value><id>2</id><roleName>角色二</roleName></value><value><id>3</id><roleName>角色三</roleName></value></item><item><key>2</key></item></return></ns2:getAllRolesResponse></soap:Body></soap:Envelope>
--------------------------------------
其中id2 是返回的拦截器.里面有soap消息
Client端实现拦截
因为client端要使用拦截器,所以 jar包还是需要的
5.4 pom.xml中配置相应的jar
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.1.12</version>
</dependency>
5.5 使用client代理类进行编写
public static void main(String[] args) {
HelloWorldService service = new HelloWorldService();//实体化服务类
HelloWorld hl = service.getHelloWorldPort();//获得接口类 (HelloWorld)
//MyRoleArray myRoleArray = hl.getAllRoles();//这个位置拦截不到信息 因为方法执行后才拦截
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(hl);//使用代理类 获取客户端
client.getInInterceptors().add(new LoggingInInterceptor());//进入拦截器
client.getOutInterceptors().add(new LoggingOutInterceptor());//检出拦截器
//编译array
MyRoleArray myRoleArray = hl.getAllRoles();//这边一定要注意顺序 拦截器必须在方法前 否则 拦截不到
List<MyRole> roles = myRoleArray.getItem();
for (MyRole myRole : roles) {
//便利里面的角色名称
for (Role role : myRole.getValue()) {
System.out.println("角色id:"+role.getId()+"角色名称:"+role.getRoleName());
}
}
}
和服务器端不同的是 先有检出 后进入
5.6 控制台监控的信息如下 :
七月 11, 2017 9:11:56 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
信息: Creating Service {http://webservice.ztgeo.com/}HelloWorldService from WSDL: http://localhost/baolu?wsdl
七月 11, 2017 9:11:58 下午 org.apache.cxf.services.HelloWorldService.HelloWorldPort.HelloWorld
信息: Outbound Message
---------------------------
ID: 1
Address: http://localhost/baolu
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=[""]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAllRoles xmlns:ns2="http://webservice.ztgeo.com/"/></soap:Body></soap:Envelope>
--------------------------------------
七月 11, 2017 9:11:58 下午 org.apache.cxf.services.HelloWorldService.HelloWorldPort.HelloWorld
信息: Inbound Message
----------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml; charset=UTF-8
Headers: {content-type=[text/xml; charset=UTF-8], Date=[Tue, 11 Jul 2017 13:11:58 GMT], Server=[Jetty(9.2.21.v20170120)], transfer-encoding=[chunked]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAllRolesResponse xmlns:ns2="http://webservice.ztgeo.com/"><return><item><key>1</key><value><id>1</id><roleName>角色一</roleName></value><value><id>2</id><roleName>角色二</roleName></value><value><id>3</id><roleName>角色三</roleName></value></item><item><key>2</key></item></return></ns2:getAllRolesResponse></soap:Body></soap:Envelope>
--------------------------------------
角色id:1角色名称:角色一
角色id:2角色名称:角色二
角色id:3角色名称:角色三
这边需要注意的是.对于客户端来讲,先有出(访问请求),才有进(返回请求), 在返回端可以看到soap信息
第六节 CXF添加自定义拦截器
添加自定义拦截器的思路和内置拦截器相同 ,只需要替换内置拦截器,自己写就好..看内置的实现了哪些方法
内置拦截器的继承关系
public class LoggingInInterceptor extends AbstractLoggingInterceptor
6.1 编写服务端自定义拦截器
package com.ztgeo.interceptor;
import java.util.List;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
public class MyInInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
public MyInInterceptor(String phase) {//实现父类的方法 ,这里是个构造方法实现
super(Phase.PRE_INVOKE);//给静态变量赋值 在进入方法前调用
}
public void handleMessage(SoapMessage message) throws Fault {
//soap消息就是客户端传入的信息
//全部封装在headers中 进行头部的解析
List<Header> headers = message.getHeaders();//获取全部头信息
//判断如果没有头部信息 那么一定有问题
if(headers==null|| headers.size()==0){
throw new Fault(new IllegalArgumentException("头信息不存在,in拦截器抛出了异常!!"));
}
//存在头信息 获取头信息 (是xml形式)
Header header = headers.get(0);
//使用w3c的dom解析该header
Element ele =(Element)header.getObject();
//获取其中的username和password节点
String username = ele.getElementsByTagName("username").item(0).getTextContent();
String password = ele.getElementsByTagName("password").item(0).getTextContent();
//约定允许访问的条件
if("wh".equals(username)){
if("123456".equals(password)){
}else{
throw new Fault(new IllegalArgumentException("用户秘钥异常~!!"));
}
}else{
throw new Fault(new IllegalArgumentException("当前用户无访问权限!"));
}
}
}
6.1 客户端添加检出自定义拦截器 用于往头部添加信息
client.getOutInterceptors().add(new AddHeaderInInterceptor("wh","12456"));//自己编写的类
6.2 编写客户端自定义拦截器
这边的自定义类 和服务端一样 只是触发拦截的时机改为了准备发送,soap message的处理 不是解析头部信息 而是往头部信息里添加username和password
package com.ztgeo.webservice;
import java.util.List;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import com.ztgeo.interceptor.AddHeaderInInterceptor;
public class Client {
//客户端调用
public static void main(String[] args) {
HelloWorldService service = new HelloWorldService();//实体化服务类
HelloWorld hl = service.getHelloWorldPort();//获得接口类 (HelloWorld)
//MyRoleArray myRoleArray = hl.getAllRoles();//这个位置拦截不到信息 因为方法执行后才拦截
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(hl);//使用代理类 获取客户端
client.getInInterceptors().add(new LoggingInInterceptor());//进入拦截器
client.getOutInterceptors().add(new LoggingOutInterceptor());//检出拦截器
//添加自定义拦截器 用于在头部添加用户信息
client.getOutInterceptors().add(new AddHeaderInInterceptor("wh","12456"));//自己编写的类
//编译array
MyRoleArray myRoleArray = hl.getAllRoles();//这边一定要注意顺序 拦截器必须在方法前 否则 拦截不到
List<MyRole> roles = myRoleArray.getItem();
for (MyRole myRole : roles) {
//便利里面的角色名称
for (Role role : myRole.getValue()) {
System.out.println("角色id:"+role.getId()+"角色名称:"+role.getRoleName());
}
}
}
}
上面代码需要 注意 发送前添加了一个头 而不是修改一个头
6.3 启动服务器端
启动正常
6.4 启动客户端 查看结果
头部携带的信息如下:
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>用户秘钥异常~!!</faultstring></soap:Fault></soap:Body></soap:Envelope>
结果正常:

第七章 使用Spring整合CXF开发WEB端
关于整合spring发布webservice 官方文档地址
7.1 新建一个web项目
骨架选择 web1.0的骨架

7.2 替换为jre1.8

7.3 目前项目处于报错状态 是因为jsp文件中 没有httpservlet

针对这种情况 实际上是缺少运行时servlet导致的,解决的方法是 添加tomcat后重新保存

7.4 pom.xml中添加spring支持
<!-- 添加Spring支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
7.5 添加cxf支持
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-core</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.5</version>
</dependency>
注意 这边已经没有了jetty的支持 改为tomcat
7.6 编写spring的配置文件 注意文件的位置 放在resources中

7.7 具体的配置
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<!-- 用于cxf相关类的实例化 -->
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<!-- 自动扫描 -->
<context:component-scan base-package="com.ztgeo" />
<!-- 定义服务提供者 -->
<jaxws:endpoint
implementor="#helloWorld"
address="/HelloWorld"
></jaxws:endpoint>
</beans>
其中 xmlns:jaxws="http://cxf.apache.org/jaxws" 为新命名的空间
implementor="#helloWorld" 为暴露的接口
adress ="/HelloWorld"为url访问时 输入的url标识符
7.8 #helloWorld需要在实现类中加入注解
@Component("helloWorld")
@WebService//同样适用webservice记性注解
public class HelloWorldImpl implements HelloWorld
7.9 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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>WS_Spring_CXF</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- Spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- Spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/webservice/*</url-pattern>
</servlet-mapping>
</web-app>
除了基本的web配置外 需要单门配置servlet 的mapping进行处理servlet
7.10 使用客户端进行解析
解析结果正常

第八章 使用spring拦截器
8.1 对于客户端,添加拦截器需要在 applicationContext中配置如下:
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean class="com.ztgeo.interceptor.MyInInterceptor"/>
</jaxws:inInterceptors>
<!-- 添加out拦截器 -->
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
</jaxws:outInterceptors>
其中 有自定义的拦截器 和 框架本身的拦截器
8.2 客户端的调用 做了些改动,因为使用spring发布的webservice 生成的类做了调整..具体的调用方法如下:
HelloWorldImplService service = new HelloWorldImplService();
HelloWorld hl = service.getHelloWorldImplPort();//获得接口类 (HelloWorld)
8.3 拦截效果如下:

本学习总结结束