webservice随记

WebService:跨平台、系统、跨语言间相互调用

CXF:
Axis(Apache)-> Axis2(Apache)
XFire -> CXF(Celtrix + XFire)(Apache)

XFire —— WebService框架
Celtrix —— ESB框架,Enterprise Service Bus,即企业服务总线

SOA(面向服务的架构)
service1、service2、service3 。。。所有组件都是“即插即用”的,每个组件提供一种服务

IBM提倡面向SOA架构,希望以"组装电脑"的方式来开发软件

1、提供各种服务的组件(WebService)
2、企业服务总线(ESB)

CXF号称是SOA框架
CXF内置一个Jetty Web服务器,优于Tomcat

-----------------------------------------------------------------------------
使用CXF开发WebService服务端:
/*************每个WebService组件需要2个部分,接口和实现类*************/
1、开发一个WebService业务接口
该接口必须使用@WebService修饰
2、开发一个WebService实现类
该实现类也要用@WebService修饰 -> @WebService(endpointInterface="org.cxf.ws.HelloWorld",serviceName="HelloWorldWs")

最终web页面里面生成的如下:
-----------------------------------------------------------------------------------------------------------
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<!--
Published by JAX-WS RI at http://jax-ws.dev.java.net. RI‘s version is JAX-WS RI 2.2.4-b01. 
-->
<!--
Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI‘s version is JAX-WS RI 2.2.4-b01. 
-->
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://impl.ws.cxf.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://impl.ws.cxf.org/" name="HelloWorldWs">
<import namespace="http://ws.cxf.org/" location="http://127.0.0.1/helloWorldWs?wsdl=1"/>
<binding xmlns:ns1="http://ws.cxf.org/" name="HelloWorldWsPortBinding" type="ns1:HelloWorld">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="sayHi">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="HelloWorldWs">
<port name="HelloWorldWsPort" binding="tns:HelloWorldWsPortBinding">
<soap:address location="http://127.0.0.1/helloWorldWs"/>
</port>
</service>
</definitions>
-------------------------------------------------------------------------------------------------------------
3、发布WebService
使用endpoint类的静态方法来发布Web Service

-----------------------------------------------------------------------------------
使用CXF开发web客户端
1、调用CXF提供的wsdl2java工具,根据wsdl文档生成相应的java代码——cmd中使用命令:wsdl http://127.0.0.1/helloWorldWs?wsdl
wsdl = web service definition language即web服务描述语言

任何语言实现了web service,都需要暴露一个wsdl文档

2、找到wsdl2java所生成的类中,一个继承了service接口的类
该类的实例可当成工厂来使用

3、调用service子类实例的getXxxPort方法,返回一个远程Web Service的代理

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

Web Service三个技术基础:
1、WSDL   Web Service Definition Language

--------------------------------------------------------------------------
xml里面的两个重要属性:
targetNamespace,相当于java里的package
xmlns命名空间,相当于java里面的import

WSDL文档:
1、web service接口
<types>...</types>
<message name="sayHi">...</message>
<message name="sayHiResponse">...</message>
<message name="getCatsByUser">...</message>
<message name="getCatsByUserResponse">...</message>
<portType name="HelloWorld">...</portType>
types元素,该元素内容就是Schema文档
2N个message元素(N为服务端下的方法数量)
portType元素,包含N个operation子元素(每个operation定义一个WS操作——方法)

(mainOccurs="0",表示出现0到1次,maxOccurs="unbounded",表示未定、无数次)

2、web service实现
binding元素,包含2N个operation元素
service元素,包含port子元素——指定指定Web Service绑定的地址

--------------------------------------------------------------------------

2、SOAP  Simple Object Access Protocol简单对象访问协议
3、UDDI

---------------------------------------------------------------------------
<xs:complexType name="sayHi">
<xs:sequence>
<xs:element name="arg0" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHiResponse">
<xs:sequence>
<xs:element name="return" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getCatsByUser">
<xs:sequence>
<xs:element name="arg0" type="tns:user" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="user">
<xs:sequence>
<xs:element name="address" type="xs:string" minOccurs="0"/>
<xs:element name="id" type="xs:int" minOccurs="0"/>
<xs:element name="name" type="xs:string" minOccurs="0"/>
<xs:element name="pass" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getCatsByUserResponse">
<xs:sequence>
<xs:element name="return" type="tns:cat" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="cat">
<xs:sequence>
<xs:element name="color" type="xs:string" minOccurs="0"/>
<xs:element name="id" type="xs:int" minOccurs="0"/>
<xs:element name="name" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
---------------------------------------------------------------------------------------
一次Web Service调用——其实并不是方法调用,而是发送SOAP消息(即XML文档片段),CXF调用的本质:
1、客户端把需要调用的参数,转换为xml文档片段(SOAP消息,input消息)
——该片段必须符合wsdl定义的格式
2、客户端通过网络,把xml文档片段传给远程服务端
3、服务器接收到xml文档片段
4、服务端解析xml片段,提取其中数据,并把数据转换为调用web service所需要的参数或对象
5、服务端执行方法
6、服务端把执行方法得到的返回值又转换生成为xml文档片段(SOAP消息,output消息)
7、服务端通过网络把xml片段传给客户端
8、客户端接收到xml文档片段
9、客户端解析xml片段,提取其中数据,并把数据转换为调用web service的返回值

从上面的调用本质来看,要一个语言支持web service,唯一的要求是:
该语言必须支持xml文档的解析、生成、支持网络传输。
所以web service支持跨平台、跨语言(本质:以xml文档为基础的数据交换)
所有的运行是在server端,client端只是发送、解析、封装、转换数据
---------------------------------------------------------------------------------------
简单来讲,wsdl描述了web service包含了如下3个方面:
** WHAT:该web service包含什么操作
** HOW:该web service应该怎么调用
** WHERE:该web service的服务地址(调用地址)

/******************************************************************************
只要得到Web Service的wsdl文档,接下来程序就可以调用Web Service
******************************************************************************/

CXF开发中,遇到系统无法自动处理的类型时,需要特殊处理:
处理思路是要提供一个转换器,该转换器负责把CXF搞不定的类型转换为CXF搞的定的类型
1、使用@XmlJavaTypeAdapter修饰无法处理的类型
使用该Annotation时,value值指定一个转换器类
该转换器就是完成类型之间的转换
2、实现自己的转换器,实现转换器时需要开发一个CXF可以搞定的类型

WebService的三个技术基础:
1、WSDL
Web Service接口:
1、types(标准的Schema)
2、2N的message
3、portType:N个operation
Web Service实现:
1、binding元素:N个更详细的operation
2、service:指定web service的服务地址
2、SOAP
根元素:Envolope:
Header元素+Body元素
默认情况下,Header元素不是强制出现的,可以在Header中放置用户名、密码等信息。
如果使用正确的话,Body元素内容应该遵守WSDL所要求的格式,如果调用错误,Body元素内容就是Fault子元素。

Web Service急需解决的问题?如何收钱?——如何进行权限控制
解决思路:
服务端要求客户端发来的input消息里面必须携带用户名、密码信息,如果没有或者不正确,则拒绝访问
(如果不用CXF等框架,则SOAP消息的生成、解析等都要通过程序来控制,无论是添加用户名、密码或者提取用户名、密码等信息都可由程序代码来完成)
如果使用CXF框架,则SOAP消息的生成、解析等都是通过CXF框架来完成。

为了让程序猿能够访问并修改CXF框架所生成的xml(SOAP消息),CXF提供了拦截器。

服务端添加拦截器:
1、获取服务端Endpoint的publish的方法返回值
2、调用该方法的getInInterceptors()、getOutInterceptors()方法来获取In、Out拦截器列表,接下来再添加拦截器即可

客户端添加拦截器:
1、调用ClientProxy的getClient(hw)方法,该方法以远程web service的代理为参数,返回值为Client对象
2、调用client对象的client.getInInterceptors().add(e)、client.getOutInterceptors().add(e)方法添加拦截器

HelloWorldWs factory = new HelloWorldWs();
HelloWorld hw = factory.getHelloWorldWsPort();//此处返回的只是远程web service的代理
Client client = ClientProxy.getClient(hw);
client.getInInterceptors().add(e);
client.getOutInterceptors().add(e);

自定义拦截器:
->需要实现Interceptor接口,实际一般直接继承AbstractPhaseInterceptor抽象类

public Class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage>{

public AuthInterceptor(){
//显示调用父类的有参构造器,一旦显示调用父类构造器之后,程序将不会隐世调用父类无参构造器
super(Phase.PRE_INVOKE); //该拦截器将会在"调用之前"拦截SOAP消息
}

//需要实现handleMessage方法,其形参即为被拦截到的Soap消息msg
//一旦程序获得了Soap消息,剩下的事情就可以解析Soap消息或者修改SOAP消息
@Override
public void handleMessage(SoapMessage msg) throws Fault{
System.out.println(msg);
}
}

CXF与Spring整合方式一(暴露本地web service接口)
在传统的javaEE的基础上,添加一层Web Service层。
此时的JavaEE应用就可以向外暴露web service,这样就允许任何平台、任何语言来调用这个javaEE

在传统SSH项目基础上添加web service步骤(注意要让struts2放行所有的web service请求):
1、复制CXF的jar包,spring的jar包
2、在Web.xml文件中配置CXF的核心控制器

<!-- 下面的配置表明所有来自/webservice/*请求,都交给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>/webservice/*</url-pattern>
</servlet-mapping>
3、在spring配置文件中,导入CXF提供Schema + xml配置文件

xmlns:jaxws="http://cxf.apache.org/jaxws"

xsi:schemaLocation="... http://cxf.apache.org/jaxws 
http://cxf.apache.org/schemas/jaxws.xsd"

ps:web应用的类加载路径有两类:
1、WEB-INF/classes目录
2、WEB-INF/lib目录

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />

4、在spring配置文件中使用jaxws:endpoint元素来暴露web service

<!-- implementor指定webservice的服务提供者,支持两种形式:
A、直接给定服务提供者的类名即接口实现类
B、设置为容器中的一个bean(依赖注入),要在bean的id前加一个#号
-->

A: 
<bean id="userService" class="org.UserService"></bean>
<jaxws:endpoint
implementor="org.xxx.Class"
address="/webservice">
</jaxws:endpoint>

B:
<bean id="userService" class="org.UserService"></bean>
<bean id="HelloWorldWs" class="org.java.HelloWorldWs" 
p:us-ref="userService" />

</bean>
<jaxws:endpoint
implementor="#HelloWorldWs"
address="/webservice">
</jaxws:endpoint>

5、添加服务端拦截器
在jaxws:endpoint里面添加jaxws:inInterceptors拦截器

<jaxws:endpoint id="helloWorld"
implementor="#HelloWorldWs"
address="/webservice">

<jaxws:inInterceptors>  
<bean class="SomeInterceptors" />
<ref bean="AnotherInterceptors" />
</jaxws:inInterceptors>

</jaxws:endpoint>

CXF与spring整合方式二(调用远程web service)
直接调用远程web service代理对象的方法进行操作
1、让我们的action以来远程web service的接口
2、复制CXF的jar包,spring的jar包,struts的jar包,以及整合包
3、在spring配置文件中,导入CXF提供Schema + xml配置文件
4、在spring配置文件中使用jaxws:client元素来配置远程web service代理
5、添加客户端拦截器
在jaxws:client里面添加jaxws:inInterceptors拦截器

<jaxws:client id="xxx" serviceClass="xxx" address="xxx" >

</jaxws-client>

时间: 2024-08-24 10:23:32

webservice随记的相关文章

4.26日病毒日即将到来,你的电脑够安全吗?

近年来流氓软件.后门程序.木马等网络威胁数量暴增,电脑病毒是个令人讨厌的字眼,却作死一般的围绕在我们每一位网民身边.为了提醒后人不忘CIH病毒带来的教训,每年的4月26日,是世界电脑病毒日.本期,小编为大家整理网络安全技术专题,防护电脑,反"作死"!欢迎大家分享,共同应对网络安全问题. 计算机安全问题,应该像每家每户的防火防盗问题一样,做到防范于未然.51CTO学院本期专题推荐: 运维中经常遇见的几种劫持,扼杀它! Web渗透测试之常见漏洞解析视频课程 2015热点安全事件原理解读与分

记一次 PHP调用Java Webservice

前两天,第三方合作公司给我们一个Webservice的链接,说是Java做的,里面有个sendMsg()方法,让我们在用php做的项目里推送消息给他们.我们公司是有用.net做的Webservice,而Java的Webservice没用过. 他们提供的东西: 1. Java Webservice:http://不给看IP:9080/mccweb/webservice/common/wsMessageService?wsdl 2. Java Webservice里的方法:sendMsg(strin

记一次动态调用WebService

这次的使用参考博客园中的ID是  生命不息,折腾不止 http://www.cnblogs.com/leolion/p/4757320.html ,感谢分享 博客园让自己慢慢的成长,少不了这些无私奉献的大牛,很是感谢. 动态调用的具体步骤为: 1)从目标 URL 下载 WSDL 数据: 2)使用 ServiceDescription 创建和格式化 WSDL 文档文件: 3)使用 ServiceDescriptionImporter 创建客户端代理类: 4)使用 CodeDom 动态创建客户端代理

记一次在Eclipse中用Axis生成webservice服务端的过程中出现的问题

问题一. Unable to find config file.  Creating new servlet engine config file: /WEB-INF/server-config.wsdd 找不到这个.wsdd的配置文件,没有自动生成! 原因是使用Eclipse自动生成axis服务端时没有执行的最后一步!如图: 当进行的这一步时,需要接着点击启动服务的按钮,之后Next按钮就会可用,点击Next按钮后就会自动生成这个.wsdd文件! 问题二. AxisFault faultCod

Android 调用webService(.net平台)

什么是webservice? Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发布.发现.协调和配置这些应用程序,用于开发分布式的互操作的应用程序.Web   Service所使用的是Internet上统一.开放的标准,如HTTP.XML.SOAP(简单对象访问协议).WSDL(webservice描述语言)等,所以Web   Service可以在任何支持这些标准的环境(Windows,Lin

VS2015发布Webservice

第一步:开启IIs:在控制面板程序——>程序功能——>打开或关闭windows功能,把“Internet信息服务”下面的“FTP服务器”.“Web管理工具”.“万维网服务”全部勾上,然后点击“确定” 2. 验证IIS是否正确安装,等待几分钟后IIS配置完成在浏览器输入http://localhost/iisstart.htm若出现下面的图标说明IIS安装成功 3.若果IIS安装不成功,会出现如下错误界面,解决该错误的方法参照 http://blog.csdn.net/mazhaojuan/ar

如何在Java中快速发布WebService服务

在实际中,您是否遇到过需要发布WebService给别人调用的需求哪?如果您是个Java的新手,客户或合作方又催得很紧,您肯定为这事儿犯愁.别急,让我们看看能用哪些工具或对象发布.Java中可供选择的方式太多,如Axis2.XFire.JWS等.郁闷了,看都看不懂,谁知道该用哪一个. 别着急,如果您特别着急,客户马上就要要,那就用下面这种方法吧: 一.通过Axis2提供的模板自动发布 这种方法非常简单,只要下载Axis包后从里面的"axis-1_4\webapps"中找到axis站点,

Jquery利用ajax调用asp.net webservice的各种数据类型(总结篇)

原文:Jquery利用ajax调用asp.net webservice的各种数据类型(总结篇) 老话说的好:好记心不如烂笔头! 本着这原则,我把最近工作中遇到的jquery利用ajax调用web服务的各种数据类型做了一个总结! 本文章没有什么高难度技术,就是记录一下,汇总一下,以便以后需要时查看! 本总结牵涉的数据类型,主要有: string,int这样的基本数据类型 ClassA这样的自定义类 List<ClassA>这样的集合类型 Dictionary这样的字典类型数据 DataSet这样

【webservice】调试方法篇(一)

开发webservice,遇到问题要知道报文的重要性.七层计算机网络,只懂最上面一层的话,永远也只是个菜鸟. 肥来正题.在开发过程中,我用到的测试软件有:tcpTrace.SoapUI 5.0.0.Wireshark. 1.tcpTrace,精悍好用的报文截看工具.超轻巧,整个工具300k(没记错的话).双击打开就是设置界面,监听端口设为本机的8811,转发的服务器设为localhost,转发的端口设为8086,意思就是监听本机的8081端口了,这是个报文转发的工具,就是把发送到我本机8081端