WebService 深入详解

一、webService 初步讲解

     1、xml 约束 schema 写法解读

<?xml version="1.0" encoding="UTF-8" ?>
<!-- schema 约束文件 -->
<schema xmlns="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://www.atguigu.com/bookSchema"
	elementFormDefault="qualified">
	<!-- elementFormDefault 是否只关联跟标签 -->
	<element name="书架">
		<complexType>
			<sequence maxOccurs="unbounded">
				<element name="书">
					<complexType>
						<sequence>
							<element name="书名" type="string" />
							<element name="作者" type="string" />
							<element name="售价" type="string" />
						</sequence>
					</complexType>
				</element>
			</sequence>
		</complexType>
	</element>
</schema>

<!-- 
	schema规范中:
	1. 所有标签和属性都需要有schema文件来定义 ,xsd规范定义中,xmlns="http://www.w3.org/2001/XMLSchema"-w3c提供;
	2. 所有的schema文件都需要有targetNamespace, 
	3. targetNamespace的值由什么来指定?
	        它的值是一个url(很有可能不存在),也就是在别人引用的时候要用的东西;
	4. 如何引入一个Schema约束?
		属性? : 用xmlns属性
		属性值: 对应的schema文件的id(targetNamespace值)
 -->
<?xml version="1.0" encoding="UTF-8"?>
<书架  xmlns="http://www.atguigu.com/bookSchema"
	   xmlns:tt="http://www.w3.org/2001/XMLSchema-instance"
	   tt:schemaLocation="http://www.atguigu.com/bookSchema book.xsd">
	<书>
		<书名>JavaScript开发</书名>
		<作者>老佟</作者>
		<售价>28.00元</售价>
	</书>
</书架>
<!-- 
	schema规范中:
	1. 所有标签和属性都需要有schema文件来定义 
	2. 所有的schema文件都需要有一个id, 但在这里它叫namespace, 
	3. namespace的值由什么来指定?
		由targetNamespace属性来指定, 它的值是一个url(很有可能不存在)
	4. 如何引入一个Schema约束?
		属性? : 用xmlns属性
		属性值: 对应的schema文件的id(namespace值)
	5. 如果引入的schema不是w3c组织定义, 必须指定schema文件的位置
	6. schema文件的位置由什么属性来指定?
		属性? : schemaLocation ? schemaLocation 由xmlns:tt来指定;
		属性值: namespace path
	7. 如果引入了N个约束, 需要给n-1个取别名
 -->

     2、Http 协议 解析

客户端连上服务器后,向服务器请求某个web资源,称之为客户端向
服务器发送了一个HTTP请求。一个完整的HTTP请求包括如下内容:
请求行
若干消息头
实体内容(可能没有,post有),如下所示 :

常用请求头(浏览器发送给服务器的数据,为了告诉服务器一些情况)
Accept: text/html,image/*    我支持的数据类型
Accept-Charset: utf-8  支持的数据的编码字符集
Accept-Encoding: gzip 支持的压缩方式
Accept-Language: en-us,zh-cn 支持的语言
Host: localhost:8888 请求的主机名
Referer: http://www.atguigu.com/index.jsp 发送请求的界面对应的url 防盗链
User-Agent: Mozilla/4.0 浏览器的相关信息
Connection: keep-Alive   请求完成后,到是断开呢还是连接着
Date: Tue, 11 Jul 2000 18:23:51 GMT 发送请求的时间
Cookie: tt=123     //后面专门讲

响应头(浏览器发送给服务器的数据,为了告诉服务器一些情况):
Location: /day05/index.jsp  告诉浏览器重新定向到指定的路径
Server:apache tomcat 使用的什么web服务器
Content-Encoding: gzip  告诉浏览器我传给你的数据用的压缩方式
Content-Length: 80 响应体的字节数
Content-Language: zh-cn 响应体数据的语言
content-type: text/html; charset=GB2312 响应体内容的类型 html/ css / image
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT 资源最后被修改的时间
Refresh: 1定时刷新
Content-Disposition: attachment; filename=aaa.zip 提示用户下载
Set-Cookie:SS=Q0=5Lb_nQ; path=/search 将cookie数据回送给ie
Expires: -1  告诉浏览器不要缓存起来 
Cache-Control: no-cache 
Pragma: no-cache  
Connection: close/Keep-Alive   是否保持连接
Date: Tue, 11 Jul 2000 18:23:51 GMT 响应的时间

     3、webService 四大术语解读

WSDL

直译 : WebService定义语言

 

1. 对应一种类型的文件.wsdl

2. 定义了web service的服务器端与客户端应用交互传递请求和响应数据的格式和方式

3. 一个web service对应一个唯一的wsdl文档

SOAPsimple object  access protocal

直译: 简单对象访问协议

 

1.是一种简单的、基于HTTP和XML的协议, 用于在WEB上交换结构化的数据

2.soap消息:请求消息和响应消息

3.http+xml片断

 

SEIWebService EndPoint Interface(终端)

直译web service的终端接口,

 

就是WebService服务器端用来处理请求的接口

@Webservice

@WebMethod

 

CXFCeltix + XFire

一个apache的用于开发webservice服务器端和客户端的框架

 

二、使用JDK原生发布webService服务

      1、创建数据发布接口及实现类,并创建发布程序类

package com.bjsxt.web.ws.ws;
import javax.jws.WebMethod;
import javax.jws.WebService;
/**
 * SEI 定义发布接口
 */
@WebService
public interface HelloWs {
	@WebMethod
	public String sayHello(String name);
}
package com.bjsxt.web.ws.ws;

import javax.jws.WebService;
/**
 *  SEI 定义发布接口实现 
 */
@WebService
public class HelloWsImpl implements HelloWs {
	@Override
	public String sayHello(String name) {
		System.out.println("调用 webService 成功 ...");
		return "welComn user :"+name;
	}
}
package com.bjsxt.web.ws.ws;

import javax.xml.ws.Endpoint;

public class StartWebService {
public static void main(String[] args) {
	String address = "http://localhost:8088/webService/HelloWs";
	Endpoint.publish(address, new HelloWsImpl());//发布webService服务
	System.out.println("发布webService成功...");
}}

 

      2、使用JDK提供的 wsimport 实现创建client

① cmd →进入目录(存放生成文件的目录,该项目中使用了工作空间目录直接生成在了编译器中) D:\Workspaces\MyEclipse 8.6\webService\src\com\bjsxt\web\ws\client>wsimport -keephttp://localhost:8088/webService/HelloWs?wsdl

② 创建测试类

package com.bjsxt.web.ws.client;

public class WebServiceTest {
	public static void main(String[] args) {
		HelloWsImplService implService = new HelloWsImplService();
		HelloWsImpl impl = implService.getHelloWsImplPort();
		System.out.println(impl.sayHello("admin"));
	}
}

      3、将上述从网络读取wsdl改为本地读取

① 将MyEclipse中的tcp/ip设置为监听

② 将请求到的网络中的wsdl文件中的内容复制在本地新建的一个wsdl文件中(注意改掉最后一行的端口)

③ 将上面一点钟的URL改为本地路径即可获得java类

三、使用公共天气预报(.net提供的webService)

1、Google”免费WebService”, 找到提供天气预报Webservice的网络地址 –http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx.wsdl

2、在MyEclipse中新建weather.wsdl,将网络中的信息复制进去

3、问题存在:

说明: 直接生成客户端代码会抛异常, 无法生成客户端代码, 解决办法:

1. 将对应的wsdl文档保存到本地

2. 修改wsdl文档的部分内容:

 <s:element ref="s:schema" /><s:any /> 替换成 <s:any minOccurs="2" maxOccurs="2"/>

备注: 这个是Java调用net的webservice都有的问题

4、使用JDK提供的wsimport生成客户端

四、支持多数据类型的入参(包括对象)

1、JDK自带webService开发中不支持多数据类型的开发,首先加入cxf的支持包:

下载地址:http://download.csdn.net/detail/u014201191/8661707

2、源码程序解析(没什么区别)

package com.atguigu.day01_ws.ws2;

import java.util.List;
import java.util.Map;
import javax.jws.WebMethod;
import javax.jws.WebService;

import com.atguigu.day01_ws.bean.Student;

@WebService
public interface DataTypeWS {

	@WebMethod
	public boolean addStudent(Student s);

	@WebMethod
	public Student getStudentById(int id);

	@WebMethod
	public List<Student> getStudentsByPrice(float price);

	@WebMethod
	public Map<Integer, Student> getAllStudentsMap();
}

 

package com.atguigu.day01_ws.ws2;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jws.WebService;

import com.atguigu.day01_ws.bean.Student;

@WebService
public class DataTypeWSImpl implements DataTypeWS {

	@Override
	public boolean addStudent(Student s) {
		System.out.println("server addStudent() "+s);
		return true;
	}

	@Override
	public Student getStudentById(int id) {
		System.out.println("server getStudentById() "+id);
		return new Student(id, "CAT", 1000);
	}

	@Override
	public List<Student> getStudentsByPrice(float price) {
		System.out.println("server getStudentsByPrice() "+price);
		List<Student> list = new ArrayList<Student>();
		list.add(new Student(1, "TOM1", price+1));
		list.add(new Student(2, "TOM2", price+2));
		list.add(new Student(3, "TOM3", price+3));
		return list;
	}

	@Override
	public Map<Integer, Student> getAllStudentsMap() {
		System.out.println("server getAllStudentsMap() ");
		Map<Integer, Student> map = new HashMap<Integer, Student>();
		map.put(1, new Student(1, "JACK1", 2345));
		map.put(3, new Student(3, "JACK3", 2375));
		map.put(2, new Student(2, "JACK2", 12345));
		return map;
	}
}

 

package com.atguigu.day01_ws.bean;

public class Student {

	private int id;
	private String name;
	private float price;

	public Student(int id, String name, float price) {
		super();
		this.id = id;
		this.name = name;
		this.price = price;
	}

	public Student() {
		super();
	}

	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 float getPrice() {
		return price;
	}

	public void setPrice(float price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", price=" + price
				+ "]";
	}

}

 

package com.bjsxt.web.ws.ws.type;

import javax.xml.ws.Endpoint;

import com.atguigu.day01_ws.ws2.DataTypeWSImpl;

public class StartWebService {
public static void main(String[] args) {
		String address = "http://localhost:8888/day01_ws/datatypews";
		Endpoint.publish(address , new DataTypeWSImpl());
		System.out.println("发布成功");
	}
}


五、CXF拦截器

1、日志拦截器

在JDK中没有拦截器,导入cxf包后,引用拦截器,就和第四大点中的一样,导入cxf包后,更好的配合JDK开发.

拦截器分类
1.按所处的位置分:服务器端拦截器,客户端拦截器
2.按消息的方向分:入拦截器,出拦截器
3.按定义者分:系统拦截器,自定义拦截器

  拦截器API
Interceptor(拦截器接口)
AbstractPhaseInterceptor(自定义拦截器从此继承)
LoggingInInterceptor(系统日志入拦截器类)
LoggingOutInterceptor(系统日志出拦截器类)

服务端拦截器:接口发布程序都一样,在终端启动的时候加入拦截器

package com.bjsxt.web.ws.ws;

import java.util.List;

import javax.xml.ws.Endpoint;

import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.message.Message;

public class StartWebService2 {
public static void main(String[] args) {
	String address = "http://localhost:8088/webService/HelloWs";
	Endpoint endpoint = Endpoint.publish(address, new HelloWsImpl());//发布webService服务
	System.out.println(endpoint);
	EndpointImpl endpointImpl  = (EndpointImpl) endpoint;
	
	//服务端的日志入拦截器
	List<Interceptor<? extends Message>> inInterceptors = endpointImpl.getInInterceptors();
	inInterceptors.add(new LoggingInInterceptor());
	
	//服务端的日志出拦截器
	List<Interceptor<? extends Message>> outInterceptors = endpointImpl.getOutInterceptors();
	outInterceptors.add(new LoggingOutInterceptor());
	System.out.println("发布webService成功...");
}}

客户端拦截器:注意要在请求前加入拦截器

package com.bjsxt.web.ws.ws;
import java.util.List;

import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.message.Message;
public class Client {
public static void main(String[] args) {
	HelloWsImplService implService = new HelloWsImplService();
	HelloWsImpl impl = implService.getHelloWsImplPort();
	//发送请求的客户端对象
	org.apache.cxf.endpoint.Client client = ClientProxy.getClient(impl);
	//客户端的日志出拦截器
	List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors();
	outInterceptors.add(new LoggingOutInterceptor());
	//客户端的日志入拦截器
	List<Interceptor<? extends Message>> inInterceptors = client.getInInterceptors();
	inInterceptors.add(new LoggingInInterceptor());
	
	String result = impl.sayHello("BOB");
	System.out.println("client "+result);
}
}

 

2、使用拦截器进行用户名密码校验

 服务端启动器以及拦截器(前面的接口发布不变)

package com.atguigu.day01_ws.ws.server;

import java.util.List;

import javax.xml.ws.Endpoint;

import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws22.EndpointImpl;
import org.apache.cxf.message.Message;

import com.atguigu.day01_ws.interceptor.CheckUserInterceptor;
import com.atguigu.day01_ws.ws.HelloWSImpl;

public class ServerTest4 {

	public static void main(String[] args) {
		String address = "http://192.168.10.165:8888/day01_ws/datatypews";
		Endpoint endpoint = Endpoint.publish(address , new HelloWSImpl());
		System.out.println(endpoint);
		EndpointImpl endpointImpl  = (EndpointImpl) endpoint;
		
		//服务端的入拦截器
		List<Interceptor<? extends Message>> inInterceptors = endpointImpl.getInInterceptors();
		inInterceptors.add(new CheckUserInterceptor());
		
		System.out.println("发布webservice成功!");
	}
}
package com.atguigu.day01_ws.interceptor;

import javax.xml.namespace.QName;

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;
/**
 * 查检用户的拦截器
 * @author xfzhang
 *
 */
public class CheckUserInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	public CheckUserInterceptor() {
		super(Phase.PRE_PROTOCOL);//在解析时候拦截
	}

	/*
 	<Envelope>
 		<head>
 			<atguigu>
 				<name>xfzhang</name>
 				<password>123456</password>
 			</atguigu>
 			<atguigu2>
 				<name>xfzhang</name>
 				<password>123456</password>
 			</atguigu2>
 		<head>
 		<Body>
 			<sayHello>
 				<arg0>BOB</arg0>
 			<sayHello>
 		</Body>
 	</Envelope>
 */
	@Override
	public void handleMessage(SoapMessage message) throws Fault {
		Header header = message.getHeader(new QName("atguigu"));
		if(header!=null) {
			Element atguiguEle = (Element) header.getObject();
			String name = atguiguEle.getElementsByTagName("name").item(0).getTextContent();
			String password = atguiguEle.getElementsByTagName("password").item(0).getTextContent();
			if("xfzhang".equals(name) && "123456".equals(password)) {
				System.out.println("Server 通过拦截器....");
				return;
			}
		}
		//不能通过
		System.out.println("Server 没有通过拦截器....");
		throw new Fault(new RuntimeException("请求需要一个正确的用户名和密码!"));
	}

}

 

客户端

package com.atguigu.day01_ws_cxf_client.test;

import java.util.List;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.message.Message;

import com.atguigu.day01_ws.ws.HelloWS;
import com.atguigu.day01_ws.ws.HelloWSImplService;
import com.atguigu.day01_ws_cxf_client.interceptor.AddUserInterceptor;

/*
 * 测试自定义拦截器
 */
public class ClientTest4 {

	public static void main(String[] args) {
		HelloWSImplService factory = new HelloWSImplService();
		HelloWS hellWS = factory.getHelloWSImplPort();
		
		//发送请求的客户端对象
		Client client = ClientProxy.getClient(hellWS);
		//客户端的自定义出拦截器
		List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors();
		outInterceptors.add(new AddUserInterceptor("xfzhang", "1234564"));
		
		String result = hellWS.sayHello("BOB");
		System.out.println("client "+result);
	}
}
package com.atguigu.day01_ws_cxf_client.interceptor;

import java.util.List;

import javax.xml.namespace.QName;

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.apache.xml.utils.DOMHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class AddUserInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	private String name;
	private String password;
	
	public AddUserInterceptor(String name, String password) {
		super(Phase.PRE_PROTOCOL);//准备协议化时拦截
		this.name = name;
		this.password = password;
	}

	/*
	 	<Envelope>
	 		<head>
	 			<atguigu>
	 				<name>xfzhang</name>
	 				<password>123456</password>
	 			</atguigu>
	 			<atguigu2>
	 				<name>xfzhang</name>
	 				<password>123456</password>
	 			</atguigu2>
	 		<head>
	 		<Body>
	 			<sayHello>
	 				<arg0>BOB</arg0>
	 			<sayHello>
	 		</Body>
	 	</Envelope>
	 */
	@SuppressWarnings("deprecation")
	@Override
	public void handleMessage(SoapMessage msg) throws Fault {
		List<Header> headers = msg.getHeaders();
		/*
		 <atguigu>
			<name>xfzhang</name>
			<password>123456</password>
		</atguigu>
		 */
		Document document = DOMHelper.createDocument();
		Element rootEle = document.createElement("atguigu");
		Element nameELe = document.createElement("name");
		nameELe.setTextContent(name);
		rootEle.appendChild(nameELe);
		Element passwordELe = document.createElement("password");
		passwordELe.setTextContent(password);
		rootEle.appendChild(passwordELe);
		
		headers.add(new Header(new QName("atguigu"), rootEle));
		System.out.println("client handleMessage()....");
	}

}

 

六、基于CXF Spring 的webService开发

           描述:本次讲解中使用了Spring Cxf 框架进行开发webService,目前没有纯cxf的开发,纯cxf开发只是加入包,辅助JDK的开发(传递数据格式,拦截器)

                   下面的源码中包含了第七大点和第八大点的项目清单

                   同时生成webService客户端文件还是一样方法 wsimport -keep url

                   Java包下载地址:http://download.csdn.net/detail/u014201191/8661707

1、服务端开发

     ① 项目清单

     ① 顺序源码

package com.atguigu.day01_ws.interceptor;

import javax.xml.namespace.QName;

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;
/**
 * 查检用户的拦截器
 * @author xfzhang
 *
 */
public class CheckUserInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	
	public CheckUserInterceptor() {
		super(Phase.PRE_PROTOCOL);
		System.out.println("CheckUserInterceptor()");
	}

	/*
 	<Envelope>
 		<head>
 			<atguigu>
 				<name>xfzhang</name>
 				<password>123456</password>
 			</atguigu>
 			<atguigu2>
 				<name>xfzhang</name>
 				<password>123456</password>
 			</atguigu2>
 		<head>
 		<Body>
 			<sayHello>
 				<arg0>BOB</arg0>
 			<sayHello>
 		</Body>
 	</Envelope>
 */
	@Override
	public void handleMessage(SoapMessage message) throws Fault {
		Header header = message.getHeader(new QName("atguigu"));
		if(header!=null) {
			Element atguiguEle = (Element) header.getObject();
			String name = atguiguEle.getElementsByTagName("name").item(0).getTextContent();
			String password = atguiguEle.getElementsByTagName("password").item(0).getTextContent();
			if("xfzhang".equals(name) && "123456".equals(password)) {
				System.out.println("Server 通过拦截器....");
				return;
			}
		}
		//不能通过
		System.out.println("Server 没有通过拦截器....");
		throw new Fault(new RuntimeException("请求需要一个正确的用户名和密码!"));
	}

}
package com.atguigu.day02_ws_cxf_spring.bean;

public class Order {

	private int id;
	private String name;
	private double price;

	public Order(int id, String name, double price) {
		super();
		this.id = id;
		this.name = name;
		this.price = price;
	}

	public Order() {
		super();
	}

	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 double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "Order [id=" + id + ", name=" + name + ", price=" + price + "]";
	}

}
package com.atguigu.day02_ws_cxf_spring.ws;

import javax.jws.WebMethod;
import javax.jws.WebService;

import com.atguigu.day02_ws_cxf_spring.bean.Order;

@WebService
public interface OrderWS {

	@WebMethod
	public Order getOrderById(int id);
}
package com.atguigu.day02_ws_cxf_spring.ws;

import javax.jws.WebService;

import com.atguigu.day02_ws_cxf_spring.bean.Order;

@WebService
public class OrderWSImpl implements OrderWS {

	
	public OrderWSImpl()  {
		System.out.println("OrderWSImpl()");
	}
	
	@Override
	public Order getOrderById(int id) {
		System.out.println("server getOrderById() "+id);
		return new Order(id, "飞机", 10000000);
	}

}

 

     ① bean.xml

<?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"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://cxf.apache.org/jaxws http://cxf.apache.org/jaxws">
  
  
  <!-- 引cxf的一些核心配置 -->
   <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" /> 
   
   <jaxws:endpoint 
     id="orderWS" 
     implementor="com.atguigu.day02_ws_cxf_spring.ws.OrderWSImpl" 
     address="/orderws">
     	<!-- <jaxws:inInterceptors>
     		<bean class="com.atguigu.day01_ws.interceptor.CheckUserInterceptor"></bean>
     	</jaxws:inInterceptors> -->
    </jaxws:endpoint>
     
</beans>

     ① 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">

	<!-- 配置beans.xml -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:beans.xml</param-value>
	</context-param>

	<!-- 
   		应用启动的一个监听器
    -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- 
   		所有请求都会先经过cxf框架
    -->
	<servlet>
		<servlet-name>CXFServlet</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>CXFServlet</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
</web-app>

 

2、客户端开发

     ① 项目清单

     ① 顺序源码

package com.atguigu.day01_ws_cxf_client.interceptor;

import java.util.List;

import javax.xml.namespace.QName;

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.apache.xml.utils.DOMHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class AddUserInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	private String name;
	private String password;
	
	
	
	public AddUserInterceptor(String name, String password) {
		super(Phase.PRE_PROTOCOL);//准备协议化时拦截
		this.name = name;
		this.password = password;
		System.out.println("AddUserInterceptor()....");
	}

	/*
	 	<Envelope>
	 		<head>
	 			<atguigu>
	 				<name>xfzhang</name>
	 				<password>123456</password>
	 			</atguigu>
	 			<atguigu2>
	 				<name>xfzhang</name>
	 				<password>123456</password>
	 			</atguigu2>
	 		<head>
	 		<Body>
	 			<sayHello>
	 				<arg0>BOB</arg0>
	 			<sayHello>
	 		</Body>
	 	</Envelope>
	 */
	@SuppressWarnings("deprecation")
	@Override
	public void handleMessage(SoapMessage msg) throws Fault {
		List<Header> headers = msg.getHeaders();
		
		/*
		 <atguigu>
			<name>xfzhang</name>
			<password>123456</password>
		</atguigu>
		 */
		Document document = DOMHelper.createDocument();
		Element rootEle = document.createElement("atguigu");
		Element nameELe = document.createElement("name");
		nameELe.setTextContent(name);
		rootEle.appendChild(nameELe);
		Element passwordELe = document.createElement("password");
		passwordELe.setTextContent(password);
		rootEle.appendChild(passwordELe);
		
		headers.add(new Header(new QName("atguigu"), rootEle));
		System.out.println("client handleMessage()....");
	}

}
package com.atguigu.day02_ws_cxf_spring.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.atguigu.day02_ws_cxf_spring.ws.Order;
import com.atguigu.day02_ws_cxf_spring.ws.OrderWS;

public class ClientTest {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]  {"client-beans.xml"});
		OrderWS orderWS = (OrderWS) context.getBean("orderClient");
		Order order = orderWS.getOrderById(24);
		System.out.println(order);
	}
}

 

     ① client-beans.xml

<?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"
   xsi:schemaLocation="http://www.springframework.org/schema/beans 
   	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://cxf.apache.org/jaxws http://cxf.apache.org/jaxws">
	<jaxws:client id="orderClient" 
		serviceClass= "com.atguigu.day02_ws_cxf_spring.ws.OrderWS" 
		address= "http://localhost:8088/day02_ws_cxf_spring/orderws?wsdl">
		
		
		<jaxws:outInterceptors>
			<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
			<bean class="com.atguigu.day01_ws_cxf_client.interceptor.AddUserInterceptor">
				<constructor-arg name="name" value="xfzhang"/>
				<constructor-arg name="password" value="123456"/>
			</bean>
		</jaxws:outInterceptors>
	</jaxws:client>
</beans>

 

七、Ajax、jQuery、HttpUrlConnection请求webService

          解析:在index.jsp这个页面中,js方法中有var data = '<soapenv:Envelope>' 这个就是我们在日志拦截器中打印得到的请求体,同样在js回调函数中,使用ajaxyq.responseXML获得响应体,直接就转换成了XML数据,获取其返回值;下面的jQuery和httpcontentservlet请求也在这个页面中包含了;

 

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<script type="text/javascript" src="jquery-1.7.2.js"></script>
<script type="text/javascript">

	$(function(){
		
		$("#btn2").click(function(){
			var name = document.getElementById("name").value;
			$.post(
				"HttpURLConnectionServlet",
				"name="+name,
				function(msg) {
					//alert(msg);
					var $Result = $(msg);
					var value = $Result.find("return").text();
					alert(value);
				},
				"xml"
			);
		});
		
		$("#btn").click(function(){ //回调函数
			var name = document.getElementById("name").value;
			var data = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://ws.day01_ws.atguigu.com/"><arg0>'+name+'</arg0></ns2:sayHello></soap:Body></soap:Envelope>';
			//alert(data);
			/* $.post(
				"http://192.168.10.165:8888/day01_ws/datatypews",
				data,
				function(msg){
					alert("------");
					var $Result = $(msg);
					var value = $Result.find("return").text();
					alert(value);
				},
				"xml"
			); */
			
			$.ajax({
				type : "post",
				url : "http://192.168.10.165:8888/day01_ws/datatypews",
				data : data,
				success : function(msg){
					alert("------");
					var $Result = $(msg);
					var value = $Result.find("return").text();
					alert(value);
				},
				error : function(msg) {
					//alert("-----"+msg);
				},
				dataType : "xml"
			});
		});
	});
	

	
	 function reqWebService() {
		var name = document.getElementById("name").value;
		var data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://ws.day01_ws.atguigu.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><q0:sayHello><arg0>'+name+'</arg0></q0:sayHello></soapenv:Body></soapenv:Envelope>';
		//XMLHttpRequest对象
		var request = getRequest();
		request.onreadystatechange = function(){
			if(request.readyState==4 && request.status==200) {
				var result = request.responseXML;
				alert(result);
				var returnEle = result.getElementsByTagName("return")[0];
				var value = returnEle.firstChild.data;
				alert(returnEle);
				alert(value);
			}
		};
		
		request.open("POST", "http://localhost:8888/day01_ws/datatypews");
		
		request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		
		request.send(data);
	}

	function getRequest() {
		var xmlHttp = null;
		try {
			// Firefox, Opera 8.0+, Safari  chrome
			xmlHttp = new XMLHttpRequest();
		} catch (e) {
			// Internet Explorer
			try {
				xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
			} catch (e) {
				xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
		}
		return xmlHttp;
	} 
</script>
</head>
<body>
	用户名:
	<input id="name" name="username" value="" />
	<br>
	<button οnclick="reqWebService()">AJax请求webservice</button>
	<button id="btn">Jquery请求webservice</button>
	<button id="btn2">HttpURLConnection请求webservice</button>
	
</body>
</html>


 

完结-------谢谢观看

 

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值