webservice学习笔记part1
?
web service1. web service的概念Webservice一种使用http发送SOAP协议数据的远程调用技术, 其中,远程调用技术可理解为: ?????? 一个系统远程调用另一个系统的服务,目标获取另一个系统的业务数据 2. webservice的三要素2.1 WSDLwsdl,全称是web server definition language, ?????? 是服务器端的定义语言,可理解为是服务器端的使用说明书 ?????? 说明接口/类、方法、参数和返回值, ?????? 随服务发布成功自动生成XML格式文档 ?????? <service>??? 服务视图,webservice的服务结点,它包括了服务端点 ?????? <binding>?? 为每个服务端点定义消息格式和协议细节 ?????? <portType>? 服务端点,描述 web service可被执行的操作方法,以及相关的消息, ??????????????????????????? 通过binding指向portType ?????? <message>? 定义一个操作(方法)的数据参数(可有多个参数) ?????? <types>????? 定义 web service 使用的全部数据类型
2.2 SOAP1. 概述: ?????? soap是一种在http上传输的xml格式的数据, ?????? 可以跨防火墙(http协议的端口是80,不会被拦截), ?????? 可以跨平台(由于soap是由xml传输数据,xml是跨平台,因此soap也可以跨平台), ?????? SOAP = HTTP + XML,并不是webservice的专有协议 2.协议结构: ?????? 必需有 Envelope 元素,将整个 XML 文档标识为一条 SOAP 消息 ?????? 可选的 Header 元素,包含头部信息 ?????? 必需有 Body 元素,包含所有的调用和响应信息 ?????? 可选的 Fault 元素,提供有关在处理此消息所发生错误的信息 3.SOAP的版本 ?????? 版本主要是1.1版本和1.2版本 ?????? 共同点: ????????????? 请求方式相同,都是post请求 ????????????? 协议的格式相同,都含有envlope和body标签 ?????? 不同点: ????????????? content-type不同: ???????????????????? 1.1版本中,Content-type: text/xml; charset=utf-8, ???????????????????? 1.2版本中,Content-Type: application/soap+xml; charset=utf-8; ????????????? 命名空间不同: ???????????????????? 1.1版本中,<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> ???????????????????? 1.2版本中,<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"> 2.3 UDDI(不重要)uddi目录服务,提供webservice服务端的注册和搜索功能
3.快速入门3.1 服务器端开发服务器端开发主要包括三个步骤: ?????? 步骤一: 开发接口 ?????? package cn.xiaoge.ws.server; public interface WeatherInterface { ?????? ?????? public String getWeather(String cityName); } ?????? 步骤二: 开发接口的实现类(实现类上一定要添加@webService 注解) ?????? @WebService ?????? public class WeatherInterfaceImpl implements WeatherInterface { ????????????? @Override ????????????? public String getWeather(String cityName) { ???????????????????? System.out.println("服务连接中..."); ???????????????????? String weather = cityName + ":晴..."; ???????????????????? return weather; ????????????? } ?????? } ?????? 步骤三: 发布服务(利用Endpoint的publish方法进行发布) ?????? public class WeatherServer { ?????? ?????? public static void main(String[] args) { ????????????? ?????? Endpoint.publish("http://127.0.0.1:12345/weather",new WeatherInterfaceImpl()); ?????? ?????? } }
确认是否发布成功: ?????? 在浏览器地址栏中输入: http://127.0.0.1:12345/weather,查看是否有内容显示 ?????? 文档说明在http://127.0.0.1:12345/weather?wsdl中 3.2 客户端开发客户端开发包括四个步骤: ?????? 1.解析服务文件 ?????? ?????? 在命令窗口中,定位到解析文件后要存放的位置,输入命令: wsimport –s . http://127.0.0.1:12345/weather?wsdl ?????? 2.创建服务视图 ?????? ?????? WeatherInterfaceImplService ?weatherInterfaceImplService = ??????????????????????????? new WeatherInterfaceImplService(); ?????? 3.创建实现类的实体 ?????? ?????? WeatherInterfaceImpl ?weatherInterfaceImpl = ?????????????????????????????????? weatherInterfaceImplService.getPort(WeatherInterfaceImpl.class); ?????? 4.调用实体类中的方法 ?????? ?????? String weather = weatherInterfaceImpl.getWeather("北京"); ?????? 5.打印结果 ?????? ?????? System.out.println(weather);
?????? 注意:解析后的文件尽量不要与原始的服务端文件放到同一个包或项目 3.3 命令wsimport???? 命令wsimport是jdk提供的一个根据使用说明书(WSDL地址)生成客户端代码工具 ???? 命令wsimport位置:%JAVA_HOME%bin ???? 命令wsimport常用的参数: ???? ?????? -d,默认的参数,生成*.class文件 ???? ?????? -s,生成*.java文件 ???? ?????? -p,指定代码的包名,如果不输入该参数,默认包名是WSDL中命名空间的倒序 ???? 命令wsimport仅支持SOAP1.1客户端的生成
4. webservice的四种客户端开发方式4.1 生成客户端调用方式(例:天气查询服务)步骤一: 解析服务 ????????????? wsimport ?-s . 服务的wsdl 步骤二: 创建服务视图 ????????????? WeatherInterfaceImplService weatherInterfaceImplService = ????????????????????????????????????????????????????????????????????? new WeatherInterfaceImplService(); 步骤三: 创建实现类的实体 WeatherInterfaceImpl weatherInterfaceImpl = ????????????????????????????????????????? weatherInterfaceImplService.getPort(WeatherInterfaceImpl.class); 步骤四: 调用实现类的方法 ?????? String weather = weatherInterfaceImpl.getWeather("北京"); 步骤五: 打印结果 ?????? System.out.println(weather); 4.2 客户端编码调用方式步骤一:解析服务 生成客户端代码 ?????? 命令: wsimport -s . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl 步骤二:创建服务视图 ?????? //1 创建url ?????? URL url = ????????????? new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl"); ?????? //2 创建QName(NameSpace的最后一定要加”/”) ?????? QName serviceName =new QName("http://WebXml.com.cn/","MobileCodeWS"); ?????? //3 创建service ?????? Service service = Service.create(url,serviceName); 步骤三:创建实现类的实体 ?????? MobileCodeWSSoap mobileCodeWSSoap = service.getPort(MobileCodeWSSoap.class); 步骤四:调用实体类中的方法 ?????? String mobileCodeInfo = mobileCodeWSSoap.getMobileCodeInfo("13666666666",""); 步骤五:打印结果 ?????? System.out.println("13666666666的详细信息:"+mobileCodeInfo); 4.3 HttpUrlConnection调用方式步骤一:创建服务地址 ?????? //1.创建服务地址(是服务的地址,不是服务的视图) ?????? URL url = new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx"); 步骤二:打开一个通向服务的连接 ?????? //2.打开一个连接 ?????? HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 步骤三:设置连接的参数 ?????? //1.设置请求方式 ?????? urlConnection.setRequestMethod("POST"); ?????? //2.设置请求的格式 ?????? urlConnection.setRequestProperty("content-type","text/xml;charset=utf-8"); ?????? //3.设置输入输出权限 ?????? urlConnection.setDoInput(true); ?????? urlConnection.setDoOutput(true); 步骤四:组织soap协议,准备发送给服务器端 ?????? String soapxml = getXml("15512345678"); ?????? OutputStream os = urlConnection.getOutputStream(); ?????? os.write(soapxml.getBytes()); 步骤五:接收服务器端的响应,并打印 ?????? //判断响应码是否是200 ????????????? if(200 == urlConnection.getResponseCode()){ ???????????????????? //准备输入流 ???????????????????? InputStream is = urlConnection.getInputStream(); ???????????????????? //将inputStream封装成字符流 ???????????????????? InputStreamReader isr = new InputStreamReader(is); ???????????????????? //将字符流成bufferedInputStream ???????????????????? BufferedReader br = new BufferedReader(isr); ???????????????????? ???????????????????? //接收拼接数据 ???????????????????? StringBuffer sb = new StringBuffer(); ???????????????????? //临时数据接收 ???????????????????? String temp = null; ???????????????????? if((temp = br.readLine()) != null){ ??????????????????????????? sb.append(temp); ???????????????????? } ???????????????????? System.out.println(sb.toString()); ???????????????????? //关闭资源流 ???????????????????? br.close(); ???????????????????? isr.close(); ???????????????????? is.close(); ????????????? } ????????????? os.close();
其中,在第四步中,用到了getXml(String phonenum);方法,具体代码如下: public static String getXml(String phoneNum){ ????????????? String soapXML = "<?xml version="1.0" encoding="utf-8"?>" ??????????????????????????? +"<soap12:Envelope ??????????????????????? ?????? ??????????????????????????? ?????? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ??????? ??????????????????????????? ?????? xmlns:xsd="http://www.w3.org/2001/XMLSchema" ??????????????????? ??????????????????????????? ?????? xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">" ?????????????????????????????????? +"<soap12:Body>" ??????????????????????????? ??? +"<getMobileCodeInfo xmlns="http://WebXml.com.cn/">" ??????????????????????????? ??? +"<mobileCode>"+phoneNum+"</mobileCode>" ??????????????????????????? ????? +"<userID></userID>" ??????????????????????????? ??? +"</getMobileCodeInfo>" ??????????????????????????? ? +"</soap12:Body>" ??????????????????????????? +"</soap12:Envelope>"; ????????????? return soapXml; ?????? } 4.4 Ajax的调用方式步骤一: ?????? 准备页面 ?????? <body> ?????? ?????? <input ?type="text" ?id="phoneNum"/> ????????????? <input type="button" value="查询" onclick="javascript:getMobileInfo();"/> ?????? </body> 步骤二: ?????? 准备ajax <script type="text/javascript"> ?????? function getMobileInfo(){ ????????????? //1.准备xmlHttpRequest ????????????? var xhr; ????????????? if (window.XMLHttpRequest) {??????????????? // 适用于所有新型浏览器 ???????????????????? xhr = new XMLHttpRequest(); ????????????? } else if (window.ActiveXObject) {???????????? // 适用于IE5.0 与 IE6.0 ???????????????????? xhr = new ActiveXObject("Microsoft.XMLHTTP"); ????????????? } ????????????? //2.打开连接 ????????????? xhr.open("post","http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx",true); ????????????? //3.注册回调函数 ????????????? xhr.onreadystatechange=function(){ ???????????????????? //判断请求是否发送成功,且相应是否成功 ???????????????????? if(4 == xhr.readyState && 200 == xhr.status){ ??????????????????????????? //如果相应成功,就打印数据 ??????????????????????????? alert(xhr.responseText); ???????????????????? } ????????????? } ????????????? ????????????? //4.设置请求头,准备soap数据 ????????????? xhr.setRequestHeader("content-type","text/xml;charset=utf-8"); ????????????????????????????????????????? var soapxml = "<?xml version="1.0" encoding="utf-8"?>" ???????????????????????????????????????????????? +"<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">" ???????????????????? ?????????????????????????????????? +"<soap12:Body>" ???????????????????????????????????????????????? ??? +"<getMobileCodeInfo xmlns="http://WebXml.com.cn/">" ???????????????????????????????????????????????? ??? +"<mobileCode>"+document.getElementById("phoneNum").value+"</mobileCode>" ???????????????????????????????????????????????? ????? +"<userID></userID>" ???????????????????????????????????????????????? ??? +"</getMobileCodeInfo>" ???????????????????????????????????????????????? ? +"</soap12:Body>" ???????????????????????????????????????????????? +"</soap12:Envelope>"; ????????????? //判断是否拼装成功 ????????????? alert(soapxml); ????????????? //5.发送数据 ????????????? xhr.send(soapxml); ????????????? ?????? } </script> 5. 用注解修改WSDL内容5.1 相关注解@WebService-定义服务,在public class上边 ?????? targetNamespace:指定命名空间 ?????? name:portType的名称 ?????? portName:port的名称 ?????? serviceName:服务名称 ?????? endpointInterface:SEI接口地址,如果一个服务类实现了多个接口,只需要发布一个接口的方法,?????????????????????????????????? 可通过此注解指定要发布服务的接口。 @WebMethod-定义方法,在公开方法上边 ?????? operationName:方法名 ?????? exclude:设置为true表示此方法不是webservice方法,反之则表示webservice方法 @WebResult-定义返回值,在方法返回值前边 ?????? name:返回结果值的名称 @WebParam-定义参数,在方法参数前边 ?????? name:指定参数的名称
注意:注解都标注在服务的实现类中,不要标记错位置
5.2 注解开发demo@WebService( ????????????? targetNamespace="http://weather.xiaoge.cn/", ????????????? serviceName="WeatherWS", ????????????? portName="WeatherWSSoap", ????????????? name="WeatherWSSoap" ????????????? ) public class WeatherInterfaceImpl implements WeatherInterface {
?????? @Override ?????? @WebMethod(operationName="getWeather") ?????? public @WebResult(name="weather") String getWeather( @WebParam(name="cityName") String cityName) { ????????????? String weather = cityName + ":晴..."; ????????????? return weather; ?????? } } 5.3 注解的作用?????? 通过注解,可以更加形像的描述Web服务。对自动生成的wsdl文档进行修改,为使用者提供一个更加清晰的wsdl文档. ?????? 当修改了WebService注解之后,会影响客户端生成的代码。调用的方法名和参数名也发生了变化,此时如果调用服务端需要重新生成客户端代码. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |