【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】
2016-01-01 11:38
761 查看
不考虑第三方框架,如果只使用JDK提供的API,那么可以使用三种方式调用WebService服务;另外还可以使用Ajax调用WebService服务。
生成源代码命令:
预备工作:开启WebService服务,使用jdk命令wsimport生成调用源代码
package com.kdyzm.ws; import javax.jws.WebService; import javax.xml.ws.Endpoint; @WebService public class MyWsServer { public String calculate(int input){ System.out.println("接收到请求数据:"+input); return input*input+""; } public static void main(String[] args) { Endpoint.publish("http://localhost:9090/ws", new MyWsServer()); System.out.println("server ready ......"); } }
生成源代码命令:
wsimport -s . http://localhost:9090/ws?wsdl[/code]
可能出现的问题参考:http://blog.sina.com.cn/s/blog_924d6a570102w21v.html
因为出现了上述问题,所以本次测试环境使用jdk 1.7。方法一:使用最简单、效率最高的方法调用WebService服务
将生成的java文件包括文件夹直接导入项目,并使用其提供的API。package com.kdyzm.call.method; import com.kdyzm.ws.MyWsServer; import com.kdyzm.ws.MyWsServerService; /** * 第一种方式就是使用wsimport命令获取所有的需要调用的代码,并直接使用这些代码完成任务 * @author kdyzm * */ public class Method1 { public static void main(String[] args) { MyWsServerService myWsServerService=new MyWsServerService(); MyWsServer myWsServer=myWsServerService.getMyWsServerPort(); String result=myWsServer.calculate(2); System.out.println(result); } }
客户端控制台打印结果:4
服务端控制台打印结果:
这种方式是使用最多的方式,也是最不容易出错、效率最高的方式,推荐使用这种方式。方法二:使用URLConnection调用WebService服务
URLConnection是JDK最底层的类,所有的网络服务底层都要使用到该类,现在尝试直接使用该类操作调用WebService服务的过程,但是首先需要获取SOAL格式的请求体,可以使用之前介绍的Web Service Explorer浏览器捕获请求体,并将该请求体进行处理转换成字符串的格式(对"进行转义\")。
使用这种方法不依赖于任何服务端提供的类和接口,只需要知道SOAP请求体的内容即可。
SOAL请求体:<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://ws.kdyzm.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <q0:calculate> <arg0>2</arg0> </q0:calculate> </soapenv:Body> </soapenv:Envelope>
转换成String字符串:String requestMessage = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " + "xmlns:q0=\"http://ws.kdyzm.com/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<soapenv:Body>" + " <q0:calculate>" + " <arg0>2</arg0>" + " </q0:calculate>" + "</soapenv:Body>" + "</soapenv:Envelope>";
测试代码:package com.kdyzm.call.method; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; /** * 第二种方式是使用UrlConnecction调用WebService服务。 */ public class Method2 { public static void main(String[] args) throws Exception { // 服务的地址 URL url = new URL("http://localhost:9090/ws"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "text/xml;charset=utf-8"); OutputStream os = connection.getOutputStream(); PrintWriter pw = new PrintWriter(os, true); String requestMessage = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " + "xmlns:q0=\"http://ws.kdyzm.com/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<soapenv:Body>" + " <q0:calculate>" + " <arg0>2</arg0>" + " </q0:calculate>" + "</soapenv:Body>" + "</soapenv:Envelope>"; // 发起请求 pw.println(requestMessage); InputStream is = connection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String temp = null; System.out.println("响应结果是:"); while ((temp = br.readLine()) != null) { System.out.println(temp); } pw.close(); os.close(); br.close(); is.close(); } }
结果和方法一种的结果相同。方法三:使用JDK提供的WebService相关API实现对WebService的服务调用
使用这种方法只需要一个接口:MyWsServer就可以了,该接口也是通过wsimport命令获取的,它和服务端对应的服务类同名。package com.kdyzm.call.method; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; import com.kdyzm.ws.MyWsServer; /** * 第三种方式:通过客户端编程实现Serice的远程调用 * 使用这种方式只需要知道一个MyWsServer接口就可以了。 * @author kdyzm * */ public class Method3 { public static void main(String[] args) throws Exception { URL url = new URL("http://localhost:9090/ws?wsdl"); Service service=Service.create(url, new QName("http://ws.kdyzm.com/", "MyWsServerService")); MyWsServer myWsServer=service.getPort(new QName("http://ws.kdyzm.com/", "MyWsServerPort"),MyWsServer.class); String result=myWsServer.calculate(2); System.out.println(result); } }
服务端和客户端的控制台打印结果同上。方法四:使用Ajax调用WebService服务
这里使用原生的js来操作该过程:<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <script type="text/javascript"> function ajaxFunction() { var xmlHttp; try { // Firefox, Opera 8.0+, Safari xmlHttp = new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("您的浏览器不支持AJAX!"); } } } return xmlHttp; } </script> </head> <body> <div id="content"></div> <!-- 第四种方式:使用ajax的方式请求调用WebService服务 --> <script type="text/javascript"> var xmlHttp = ajaxFunction(); var wsUrl = "http://localhost:9090/ws"; var requestMessage = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " + "xmlns:q0=\"http://ws.kdyzm.com/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<soapenv:Body>" + " <q0:calculate>" + " <arg0>2</arg0>" + " </q0:calculate>" + "</soapenv:Body>" + "</soapenv:Envelope>"; xmlHttp.open("POST", wsUrl, true); xmlHttp.setRequestHeader("Content-Type", "text/xml;charset=utf-8"); xmlHttp.onreadystatechange = _callback; xmlHttp.send(requestMessage); function _callback() { if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200) { var retXml = xmlHttp.responseXML; var result = retXml.getElementsByTagName("return")[0]; document.getElementById("content").innerHTML = result.firstChild.nodeValue;; } } } </script> </body> </html>
注意,result对象是[Object Element]类型的,需要调用.firstChild.nodeValue方法获取文本值。
使用这种方式只适合在IE浏览器中使用,使用谷歌浏览器或者火狐浏览器都失败了,出现的异常情况: xmlHttp.open("POST", wsUrl, true);这句代码设置了请求方式是POST,但是实际上没管用,请求方式变成了OPTION,statckOverFlow上有人解释先使用OPTION的请求方式测试和服务器的连通性,然后才使用POST方式发送请求数据,所以服务器才会报出:
不管说法是否正确,该问题在这里暂时没法解决,先存档;在IE中运行正常:
服务器控制台打印结果同上。注解
WebService的注解包括:@WebService,@WebMethod,@WebResult,@WebParam,具体使用方法见下图
还有一个最重要的注解,使用该注解能够将服务发布为符合SOAP1.2规范的WebService服务:
@BindingType(value=SOAPBinding.SOAP12HTTP_BINDING)
客户端使用SOAP1.1可以正常调用服务端1.2的服务,但是反之则不行,所以最好将发布的服务都做成SOAP1.2的。
相关文章推荐
- Java读书笔记(1)-异常处理
- Spring Batch入门教程及其框架搭建
- 2016/1/1 运算符 笔记整理 接2015/12/30 Java 语法
- Spring不能注入Static变量的原因及Spring注入静态变量
- Eclipse搭建android环境及Genymotion模拟器安装问题解决方法
- Java在制作jar包时引用第三方jar包的方法
- Java对象的硬、软、弱和虚引用
- android eclipse 环境搭建
- Eclipse启动时出现错误 An internal error occurred during: “Updating indexes”
- 导致MyEclipse内存不足的原因分析及解决办法
- JAVA关于This的用法
- java interface 中定义的class 是否是static 的验证
- java装饰模式
- MyEclipse和Eclipse区别与联系
- Java 48个关键字
- spring-framework-3.2.4与hibernate-release-4.3.5下使用HibernateDaoSupport抛出异常
- Java 模拟队列(一般队列、双端队列、优先级队列)
- Android N 将替代使用 OpenJDK
- [Eclipse] Importerror no module named pwd-----getpass.getuser()
- Java注解实践