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 运行后输出
![](http://or316jtnw.bkt.clouddn.com//17-7-11/57009298.jpg)
第四章 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 拦截效果如下:
本学习总结结束