Web Service 学习笔记

下载:WebService学习笔记.txt

Web Service
    不是框架 ,也不是一种技术.
    而是一种跨平台,跨语言的规范.

集中解决
    远程调用
    跨平台调用
    跨语言调用

实际案例
    同一公司,新旧系统的整合
    不公司的业务整合
    内容整合


CXF
Axis (Apache) -> Axis2
XFire -> XFire + Celtrix = XFC ->CXF
                 |	 |
                 |	 |
                 |	 ---(ESB框架)
                 |
                 --(Web Service 框架)



SOA(面向服务的框架)
    Service1,Service2,Service3  所有的组件都是"即插即用"的.

    提倡的SOA架构: 希望以"组装台式电脑"的方式来开发软件.

    1.各种提供服务的组件. (Web Service)
    2.企业服务总线(Enterprise Service Bus , ESB)

    CXF号称是SOA框架


--------------------------------
使用CXF开发Web Service服务器端
1.开发WebService业务接口
@WebService  <- javax.jws.  java公司提供了规范, CXF提供了框架
public interface Hello {
public String sayHello(String str);
}

2.开发业务的实现类
@WebService(
		endpointInterface = "com.memorycat.testwebservice.service.Hello",
		serviceName = "HelloWorld")
public class HelloWorld implements Hello {
	@Override
	public String sayHello(String str) {
		// TODO Auto-generated method stub
		System.out.println("HelloWorld - sayHello");
		return str + "hiiiiiiiiiiiiii";
	}
}

3.发布
public static void main(String[] args) {
	Endpoint.publish("http://127.0.0.1:70/hello", new HelloWorld());
	System.out.println("发布完成");
}


4.浏览器打开
http://127.0.0.1:70/hello?wsd

------------------
使用CXF开发Web Service客户端
1.调用CXF提供的wsdl2java工具,根据wsdl文档生成响应的java代码
wsdl-Web Service Definition Language

D:\workspace_default\TestWebServiceClient\src>wsdl2java http://127.0.0.1:70/hello?wsdl
等几下,就会自动生成一堆文件

那玩意在cxf下载的zip解压后的D:\jar\cxf\apache-cxf-2.7.14\bin里,,(把这加入path就好了)


2.编写测试代码
public class Tester {	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HelloWorld factory=new HelloWorld(); //注意,他是个工厂.
		Hello hello = factory.getHelloWorldPort();//调用的他的get**Port(),返回远程WebServie的代理方法
		System.out.println(hello.sayHello("MCat"));
	}				
}





-----------
参数,返回值类型
    1.当形参,返回值是String,基本数据类型时,CXF可以轻松处理.
    2.当形参,返回值是JavaBean式的复合类,List集合,数组等时,
    CXF也可以很好的处理.
    3.但有一些像Map,非JavaBean式的复合类,CXF是处理不了的.


------------
WebService的三个技术基础
WebService的三个技术基础
	1.WSDL
		Web Service Difinition Language - Web Service 定义语言
		WebService接口
			1.types(标准的Schema)
			2.2N的message
			3.porttype --N个operation
		WebService实现
			1.binding元素	--N个更详细的operation
			2.service		--指定WebService的服务器地址
			
	2.SOAP
		Header(可选)
			一般添加一些自定义信息,如帐号密码之类的
		Body(默认)
			当WebService交互正确时,Body元素里的内容由WSDL控制.
			当WebService交互出错时,Body元素里的内容将是Fault子元素.
			
	3.UDDI


-------
xml里的2个属性

targetNamespace --> java的package
targetNamespace="http://impl.service.testwebserviceserver.memorycat.com/"
xmlns    --> java中的import


---------
本质
1.客户端把调用方法参数,转换生成xml文档片段(SOAP消息)
该文档必须符合wsdl定义的格式
2.通过网络把xml文档重传给服务器
3.服务器收到xml文档片段
4.服务器解释xml文档片段,提取其中的数据.
并把数据转调用WebService所需的数据的参数值
5.服务器执行
6.服务器执行方法的返回值,再次转换生成为xml文档片段
该文档必须符合wsdl定义的格式
7.通过网络把xml文档重传给客户端
8.客户端接收到xml文档片段
9.客户端解释xml文档片段,提取其中的数据.
并把数据转调用WebService所需的返回值


-------------
拦截器

服务器端


实现Interceptor接口,但是一般继承AbstractPhaseInterceptor

EndpointImpl publish = (EndpointImpl) Endpoint.publish("http://127.0.0.1:70/hello", new HelloWorld());
publish.getInInterceptors().add(new LoggingInInterceptor());


传入信封
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
	<S:Body>
		<ns2:sayHello xmlns:ns2="http://service.testwebserviceserver.memorycat.com/">
			<arg0>MCat</arg0>
		</ns2:sayHello>
	</S:Body>
</S:Envelope>

传出信封
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns2:sayHelloResponse xmlns:ns2="http://service.testwebserviceserver.memorycat.com/">
			<return>MCathiiiiiiiiiiiiii</return>
		</ns2:sayHelloResponse>
	</soap:Body>
</soap:Envelope>



客户端
public static void main(String[] args) {
	HelloWorld factory=new HelloWorld();
	Hello hello = factory.getHelloWorldPort();
	Client client = ClientProxy.getClient(hello);
	client.getInInterceptors().add(new LoggingInInterceptor());
	client.getOutInterceptors().add(new LoggingOutInterceptor());
	System.out.println(hello.sayHello("MCat"));
}

传出信封
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns2:sayHello xmlns:ns2="http://service.testwebserviceserver.memorycat.com/">
			<arg0>MCat</arg0>
		</ns2:sayHello>
	</soap:Body>
</soap:Envelope>

传入信封
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns2:sayHelloResponse xmlns:ns2="http://service.testwebserviceserver.memorycat.com/">
			<return>MCathiiiiiiiiiiiiii</return>
		</ns2:sayHelloResponse>
	</soap:Body>
</soap:Envelope>




自定义拦截器
服务端
package com.memorycat.testwebserviceserver.service.test;
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;
import org.w3c.dom.NodeList;

public class MyAuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
	
	public MyAuthInterceptor(){
		super(Phase.INVOKE);
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public void handleMessage(SoapMessage smsg) throws Fault {
		// TODO Auto-generated method stub
		
		System.out.println(">>>" + smsg);
		
		List<Header> headers = smsg.getHeaders();
		if (headers.size() > 0) {
			Header header = headers.get(0);
			Element element = (Element) header.getObject();
			NodeList name = element.getElementsByTagName("username");
			NodeList psw = element.getElementsByTagName("userpsw");
			if (name.getLength() > 0 || psw.getLength() > 0) {
				String username = name.item(0).getTextContent();
				String userpsw = psw.item(0).getTextContent();
				if (username.equals("asd") && userpsw.equals("qwe")) {
					System.out.println("身份合法:" + username + "\t" + userpsw);
				} else {
					
					throw new Fault(new IllegalAccessError("身份不合法"));
				}
				
			} else {
				
				throw new Fault(new IllegalAccessError("缺少username或userpsw元素"));
			}
			
		} else {
			throw new Fault(new IllegalAccessError("请求参数不正确哟"));
		}
	}
}

客户端
package com.memorycat.testwebserviceserver.service;
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.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;


public class MyClientAuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	public MyClientAuthInterceptor(){
		super(Phase.PREPARE_SEND);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void handleMessage(SoapMessage smsg) throws Fault {
		// TODO Auto-generated method stub
		List<Header> headers = smsg.getHeaders();
		
		
		
		Document document = DOMUtils.createDocument();
		Element elementAuth = document.createElement("auth");
		Element elementUserName = document.createElement("username");
		elementUserName.setTextContent("asd");
		Element elementuserPsw = document.createElement("userpsw");
		elementuserPsw.setTextContent("qwe");
		elementAuth.appendChild(elementUserName);
		elementAuth.appendChild(elementuserPsw);
		/*
		 * <auth>
		 * 	<username>asd</username>
		 * 	<userpsw>qwe</userpsw>
		 * </auth>
		 *  
		 */
		
		headers.add(new Header(new QName("MemoryCat"), elementAuth));
	}


}


---------------------
CXF与Spring整合发布
1.导入CXF的Jar包
2.在web.xml配置CXF的核心控制器 CXFServlet
		<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>

3.在Spring配置文件beans.xml中导入CXF的Schema,xml配置文件
	<beans xmlns="http://www.springframework.org/schema/beans"
			xmlns:context="http://www.springframework.org/schema/context"
			xmlns:jaxws="http://cxf.apache.org/jaxws"
			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			xsi:schemaLocation="http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
			http://www.springframework.org/schema/context
			http://www.springframework.org/schema/context/spring-context-3.0.xsd
			http://cxf.apache.org/jaxws
			http://cxf.apache.org/schemas/jaxws.xsd">

		注意此处的
				xmlns:jaxws="http://cxf.apache.org/jaxws"
					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-extension-soap.xml" />
		<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
		
		关于classpath问题
			classpath 指向 WEB-INF/classes/ 还有 WEB-INF/lib/ 
			且优先级 lib>classes
		
		classpath 和 classpath* 区别:
			classpath:只会到你的class路径中查找找文件;
			classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找.




4.在Spring配置文件中使用jaxws:endpoint元素来暴露WebService
	<jaxws:endpoint address="/hello"
		implementor="com.memorycat.testwebserviceserver.service.impl.HelloWorld"> <!-- 如果是想引用spring中bean.这里加一个#号,如#userWebService -->
	</jaxws:endpoint>
		

5.添加拦截器
	<jaxws:endpoint address="/hello"
		implementor="com.memorycat.testwebserviceserver.service.impl.HelloWorld">
		<jaxws:inInterceptors>
			<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
			<bean class="com.memorycat.testwebserviceserver.interceptor.MyAuthInterceptor" />
		</jaxws:inInterceptors>
		<jaxws:outInterceptors>
			<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
		</jaxws:outInterceptors>
	</jaxws:endpoint>


--------------
服务端和客户端的配置区别
服务端,其Bean是实现类
	<jaxws:endpoint address="/hello"
		implementor="com.memorycat.testwebserviceserver.service.impl.HelloWorld">
	</jaxws:endpoint>
客户端,其Bean是接口
	<jaxws:client id="wsHello"
		serviceClass="com.memorycat.testwebserviceserver.service.Hello"
		address="http://127.0.0.1:8080/MySpringMVCWithWebService/ws/hello">
	</jaxws:client>
	
调用代码
	WebApplicationContext context = WebApplicationContextUtils
		.getWebApplicationContext(request.getSession()
				.getServletContext());
	Hello hello = (Hello) context.getBean("wsHello");		
	response.getWriter().println(hello.sayHello(who));
	-------
	可以注入式
		@Resource(name="wsHello")
		Hello hello ;

评论列表
2015-03-05 14:40:02 1

工程例子,,但不含jar包 webservice例子.rar

包含2个例子

   1.普通java工程整合webservice

   2. springmvc整合webservice