很多新手一听到接口就蒙逼,不知道接口是什么!其实接口就是RPC,通过远程访问别的程序提供的方法,然后获得该方法执行的接口,而不需要在本地执行该方法。就是本地方法调用的升级版而已,我明天会上一篇如何通过socket实现rpc,以及服务的注册和动态上下线。这里先上一篇RPC的实现者一webservice,便于后面理解源码执行过程,框架就是在原理的基础上提供更加便捷的使用而已,协议就是基于TCP或UDP之上,服务者和调用者之间约定消息按照什么样的格式发送以及解析罢了。协议没什么高深莫测的。

原文和作者一起讨论:http://www.cnblogs.com/intsmaze/p/6055684.html

  下面是我多年前学习webservice时,做的笔记,今天整理一下,分享出来,为我源码剖析RPC做准备。  

  WebService,顾名思义就是基于Web的服务。它使用Web(HTTP)方式,接收和响应外部系统的某种请求,从而实现远程调用。我们可以调用互联网上查询天气信息Web服务,然后将它嵌入到我们的程序(C/S或B/S程序)当中来,用户可以在我们的网点看到天气信息,他会认为我们为他提供了很多的信息服务,但其实我们只是简单调用了一下服务器上的一段代码来调用别人写好的WebService。WebService可以将你的服务(一段代码)发布到互联网上让别人去调用,也可以调用别人机器上发布的WebService,就像使用自己的代码一样.

  webservice是两个软件系统之间的远程调用,这里的调用是跨语言的调用。两个不同的应用程序之间通过xml进行数据交互的。这样任何一种语言都可以解析xml文件中的数据。数据进行交互遵循的协议是http协议。http协议,以及我们用jdbc访问数据库其实底层都是依赖socket连接。比我我们经常在别的网站登录第三方账号也可以登录,其实也是用的webservice,别的网站拿到账号到第三方提供的账号服务去验证。

  在JDK1.6以后JAX-WS规范定义了如何发布一个webService服务。
  JAX-WS是指Java Api for XML – WebService.
  用Jdk1.6.以后的版本发布一个WebService服务.
  与Web服务相关的类,都位于javax.jws.*包中。
  主要类有:
  @WebService - 它是一个注解,将 Java 类标记为实现 Web Service,或者将 Java 接口标记为定义 Web Service 接口。
  Endpoint – 此类为端点服务类,它的方法publish用于将一个已经添加了@WebService注解对象绑定到一个地址的端口上,接收两个参数,一个是本地的服务地址,二是提供服务的类。
  如何发布一个web服务:
  1、在类上添加@WebService注解。
  2、通过EndPoint(端点服务)static Endpoint.publish(String address, Object implementor) 发布一个webService。
  EndPoint发布完成服务以后,将会启动一个独立的线程运行,这个启动的线程其实就是一个servicesocket,它会接收来至其他端的socket连接。
  其他注意事项:
  1,给类添加上@WebService注解后,类中所有的非静态方法都将会对外公布。不支持静态方法,final方法。
  2,如果希望某个方法(非static,非final)不对外公开,可以在方法上添加@WebMethod(exclude=true),阻止对外公开。
  3,如果一个类上,被添加了@WebService注解,则必须此类至少有一个可以公开的方法,否则将会启动失败。

@WebService
public class HelloService {
public String sayHello( String intsmaze){
System.out.println("sayHello()...");
return "hello " + intsmaze;
}
public String sayHello2(String intsmaze){
return "hello " + intsmaze;
}
public static void main(String[] args) {
Endpoint.publish("http://127.0.0.1:6789/hello ", new HelloService());
     //这个地方其实就是进行了封装,里面根据指定参数启动了一个servicesocket,并且生成了一个WSDL文档。
System.out.println("Server ready...");
}
}

  服务发布成功了,如何调用呢?请看说明书-WSDL:
  任何一个服务在地址栏输入服务地址加?wsdl 如:http://127.0.0.1:6789/hello ?wsdl
  目前不是访问webService,只是获取一个用于描述WebService的说明文件,即:wsdl文件.wsdl- WebService Description Language,是以XML文件形式来描述WebService的”说明书”,有了说明书,我们才可以知道如何使用或是调用这个服务。

wsimport.exe是jdk自带的,可以根据wsdl文档生成客户端调用代码。
当然,无论服务器端的WebService是用什么语言写的,都将在客户端生成Java代码.服务器端用什么写的并不重要.
注意生成的这些代码服务端并没有,不是从服务端下载的。
wsimport.exe位于JAVA_HOME\bin目录下.
常用参数为:
-d<目录>  - 将生成.class文件。默认参数。
-s<目录> - 将生成.java文件。
-p<生成的新包名> -将生成的类,放于指定的包下:-p com.intsmaze.demo
(wsdlurl) - http://server:port/service?wsdl,必须的参数。
示例:
C:/> wsimport –s . http://192.168.0.100/one?wsdl
注意:-s不能分开,-s后面有个小点,用于指定源代码生成的目录。点即当前目录。(注意.前后有空格)
如果使用了-s参数则会在目录下生成两份代码,一份为.class代码。一份为.java代码。
.class代码,可以经过打包以后使用。java代码可以直接Copy到我们的项目中运行。
然后只需要根据wsdl文件提供的信息调用生成类提供的方法。建议从下往上看。

  wsimport.exe是jdk自带的,可以根据wsdl文档生成客户端调用java代码,当然如果是用其他语言的类似工具,解析wsdl后将会生成对应语言的代码,这里只是用java为例子,注意这些代码不是通过服务端下载的,而是通过解析wsdl生成对应java文件(就是一个本地IO)。
  wsimport.exe位于JAVA_HOME\bin目录下.

常用参数为:
-d<目录> - 将生成.class文件。默认参数。
-s<目录> - 将生成.java文件。
-p<生成的新包名> -将生成的类,放于指定的包下:-p com.intsmaze.demo
(wsdlurl) - http://server:port/service?wsdl,必须的参数。

示例:C:/> wsimport –s . http://192.168.0.100/one?wsdl
注意:-s不能分开,-s后面有个小点,用于指定源代码生成的目录。点即当前目录。(注意.前后有空格)
如果使用了-s参数则会在目录下生成两份代码,一份为.class代码。一份为.java代码。.class代码,可以经过打包以后使用。java代码可以直接Copy到我们的项目中运行。

生成代码

  然后只需要根据wsdl文件提供的信息调用生成类提供的方法。建议从下往上看。

wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://jdkservice.intsmaze.com/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:ns1="http://schemas.xmlsoap.org/soap/http"
name="HelloServiceService"
targetNamespace="http://jdkservice.intsmaze.com/">这是服务端的包结构,一般来说通过注解修改最多,不要暴露出去!
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://jdkservice.intsmaze.com/"
elementFormDefault="unqualified" targetNamespace="http://jdkservice.intsmaze.com/" version="1.0">
<xs:element name="sayHello" type="tns:sayHello"/>
<xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/>
<xs:complexType name="sayHello">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string"/>
<xs:element name="arg1" type="xs:int"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHelloResponse">6,子元素说明了它的类型,已经是参数还是返回值
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="sayHelloResponse">5,通过element可以知道参数类型
<wsdl:part element="tns:sayHelloResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="sayHello">
<wsdl:part element="tns:sayHello" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="HelloService">3,找到标签它的子元素就是提供的方法
<wsdl:operation name="sayHello">方法名
<wsdl:input message="tns:sayHello" name="sayHello"></wsdl:input>
4,输入参数,通过message的属性可以知道参数类型,但是如果生成本地代码,通过调用函数就可以知道参数类型了。
<wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse">输出参数
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="HelloServiceServiceSoapBinding" type="tns:HelloService">2,根据type的属性找到对应的标签
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="sayHello">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="sayHello">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="sayHelloResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloServiceService">服务的名称,创建具体服务对象。
<wsdl:port binding="tns:HelloServiceServiceSoapBinding" 1,根据这个名称找到对应的标签
name
="HelloServicePort">服务对象调用getHelloServicePort()获取端口返回服务接口。
<soap:address location="http://127.0.0.1:7777/hello"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
package com.intsmaze.jdkservice;
/**
* 通过wsimport生成客户端代码调用webservice服务
*/
public class App {
public static void main(String[] args) {
/**
* wsdl:<service name="HelloServiceService">
*/
HelloServiceService hss = new HelloServiceService();
/**
* wsdl:<port name="HelloServicePort" binding="tns:HelloServicePortBinding">
*/
HelloService soap = hss.getHelloServicePort();
String str = soap.sayHello("intsmaze");//这里我们看视乎在调用我们本地的方法,其实内部把发送数据组装为soap协议,
然后把
数据发送到了服务端,服务端的线程接收到请求处理返回了数据。
System.out.println(str);
}
}

 我们使用过HttpWatch获取的HTTP的调用过程,并获得了HTTP的请求头及其他请求的详细信息。既然WebServie也是通过HTTP进行通信的,能不使用HTTPWatch来获取它的请求过程呢?我们的代码不仅仅是向服务器发送的HTTP协议,更具体的说应该叫SOAP协议,它是WebService进行通信的基础。为了获取SOAP数据发送和接收的格式。我们有必要使用一个工具来深入的了解WebService.
  我们使用TCP/IP Monitor来监控拦截请求和响应具体数据的完整过程。 

以下发出HTTP请求

  响应的信息,同发送信息一样,先必须是HTTP协议,然后再遵循SOAP协议。

java接口调用——webservice就是一个RPC而已的更多相关文章

  1. OpenCV4Android开发之旅(一)----OpenCV2.4简介及 app通过Java接口调用OpenCV的示例

    转自:  http://blog.csdn.net/yanzi1225627/article/details/16917961 开发环境:windows+ADT Bundle+CDT+OpenCV-2 ...

  2. Java动态调用webService,axis2动态调用webService

    Java动态调用webService axis2动态调用webService >>>>>>>>>>>>>>>& ...

  3. 十分钟搭建redis单机版 & java接口调用

    本次单机版redis服务器搭建采用的包为redis-3.0.0.tar.gz,主要是记录下安装的心得,不喜勿喷! 一.搭建redis服务器单机版 1.上传redis-3.0.0.tar.gz到服务器上 ...

  4. java如何调用webservice接口

    java调用WebService可以直接使用Apache提供的axis.jar自己编写代码,或者利用Eclipse自动生成WebService Client代码,利用其中的Proxy类进行调用.理论上 ...

  5. struts1+spring+myeclipse +cxf 开发webservice以及普通java应用调用webservice的实例

    Cxf + Spring+ myeclipse+ cxf 进行  Webservice服务端开发 使用Cxf开发webservice的服务端项目结构 Spring配置文件applicationCont ...

  6. java 接口调用

    生产中遇到过这种问题,记录下java的接口调用问题. 一种是json方式: public static String sendPost(String url, JSONObject obj)throw ...

  7. java 接口和抽象类的一个最大的区别

    写在前面,下面是在百度百科上看到的,之前就看过,这次再看感觉有更深的体会,真的是这样,每一个脚印都会留下痕迹 java接口和java抽象类有太多相似的地方,又有太多特别的地方,这里说下两者之间的一个最 ...

  8. 百度鹰眼Java接口调用增删改查实例

    因感觉百度鹰眼的使用场景比较符合实际业务,于是对百度鹰眼做了简单功能调试.刚开始使用springframework封装的RestTemplate,但是测试提示ak参数不存在.后又试了几种方法,均提示a ...

  9. Java 递归调用 recursive 给一个参数 返回一大堆

    需求: 需要组装成对象多层嵌套式的 json字符串; 想到使用 递归来完成这个多层嵌套: 憋了四个小时,终于写出来了; 先看效果: 数据库中的数据: 拼装后的效果: [ EmpVO{ ename='孙 ...

随机推荐

  1. 手动导入swift三方danielgindi/Charts到OC工程中教程

    1.到github网址上下载zip压缩包https://github.com/danielgindi/Charts 2.然后将解压后的文件夹整个拖到自己的工程文件夹下(很多教程只让拖xcodeproj ...

  2. [转载]敏捷开发之Scrum扫盲篇

    现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP...      为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述S ...

  3. Atitit.cto 与技术总监的区别

    Atitit.cto 与技术总监的区别 1. 核心区别1 2. Cto主要职责1 3. 如何提升到cto1 4. CTO五种基本的必备素质:2 5. 2 1. 核心区别 技术总监(Chief Tech ...

  4. 【每日一linux命令1】linux命令路径

    一.路径: 执行命令前必须要考虑的一步是命令的路径,若是路径错误或是没有正确的指定,可能导致错误 的执行或是找不到该命令.要知道设置的路径,可执行以下命令: echo $PATH 显示结果: 这时我们 ...

  5. IM 去中心化概念模型与架构设计

    今天打算写写关于 IM 去中心化涉及的架构模型变化和设计思路,去中心化的概念就是说用户的访问不是集中在一个数据中心,这里的去中心是针对数据中心而言的. 站在这个角度而言,实际上并非所有的业务都能做去中 ...

  6. Xamarin.iOS开发初体验

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0

  7. 基于Kubernetes在AWS上部署Kafka时遇到的一些问题

    作者:Jack47 转载请保留作者和原文出处 欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 交代一下背景:我们的后台系统是一套使用Kafka消息队列的数据处理管线 ...

  8. 【Java并发编程实战】-----“J.U.C”:CountDownlatch

    上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...

  9. 轻量级表达式树解析框架Faller

    有话说 之前我写了3篇关于表达式树解析的文章 干货!表达式树解析"框架"(1) 干货!表达式树解析"框架"(2) 干货!表达式树解析"框架" ...

  10. ABP教程-通过ABPboilerplate模版创建项目

    开篇说明: 此篇博客是属于半教程博客,为什么说是半教程呢.因为我不会打算说什么理论性的东西,没必要.要看理论性的资料以及基础信息,请前往tkb至简和@阳光铭睿的博客查看文档资料. 开发环境: vs20 ...