【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】

时间:2022-05-06 06:32:53

不考虑第三方框架,如果只使用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

  可能出现的问题参考: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

  服务端控制台打印结果:

  【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】

  这种方式是使用最多的方式,也是最不容易出错、效率最高的方式,推荐使用这种方式。

方法二:使用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方式发送请求数据,所以服务器才会报出:

  【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】

  不管说法是否正确,该问题在这里暂时没法解决,先存档;在IE中运行正常:

  【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】

  服务器控制台打印结果同上。

注解

  WebService的注解包括:@WebService,@WebMethod,@WebResult,@WebParam,具体使用方法见下图

  还有一个最重要的注解,使用该注解能够将服务发布为符合SOAP1.2规范的WebService服务:

  @BindingType(value=SOAPBinding.SOAP12HTTP_BINDING)

  客户端使用SOAP1.1可以正常调用服务端1.2的服务,但是反之则不行,所以最好将发布的服务都做成SOAP1.2的。  

  【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】

【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】的更多相关文章

  1. 【Java EE 学习 80 上】【WebService】

    一.WebService概述 什么是WebService,顾名思义,就是基于Web的服务,它使用Http方式接收和响应外部系统的某种请求,从而实现远程调用.WebService实际上就是依据某些标准, ...

  2. 【Java EE 学习 67 下】【OA项目练习】【SSH整合JBPM工作流】【JBPM项目实战】

    一.SSH整合JBPM JBPM基础见http://www.cnblogs.com/kuangdaoyizhimei/p/4981551.html 现在将要实现SSH和JBPM的整合. 1.添加jar ...

  3. 【Java EE 学习 77 下】【数据采集系统第九天】【使用spring实现答案水平分库】【未解决问题:分库查询问题】

    之前说过,如果一个数据库中要存储的数据量整体比较小,但是其中一个表存储的数据比较多,比如日志表,这时候就要考虑分表存储了:但是如果一个数据库整体存储的容量就比较大,该怎么办呢?这时候就需要考虑分库了, ...

  4. 【Java EE 学习 72 下】【数据采集系统第四天】【移动&sol;复制页分析】【使用串行化技术实现深度复制】

    一.移动.复制页的逻辑实现 移动.复制页的功能是在设计调查页面的时候需要实现的功能.规则是如果在同一个调查中的话就是移动,如果是在不同调查中的就是复制. 无论是移动还是复制,都需要注意一个问题,那就是 ...

  5. 【Java EE 学习 33 上】【JQuery样式操作】【JQuery中的Ajax操作】【JQuery中的XML操作】

    一.JQuery中样式的操作 1.给id=mover的div采用属性增加样式.one $("#b1").click(function(){ $("#mover" ...

  6. WebService登陆验证四种方式

    在这个WEB API横行的时代,讲WEB Service技术却实显得有些过时了,过时的技术并不代表无用武之地,有些地方也还是可以继续用他的,我之所以会讲解WEB Service,源于我最近面试时被问到 ...

  7. CSS学习(一)---使用CSS的四种方式

      1. 行内样式 例: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  8. 把 Console 部署成 Windows 服务,四种方式总有一款适合你!

    一:背景 1. 讲故事 上周有一个项目交付,因为是医院级项目需要在客户的局域网独立部署. 程序: netcore 2.0,操作系统: windows server 2012,坑爹的事情就来了, net ...

  9. 【Java EE 学习 29 下】【JDBC编程中操作Oracle数据库】【调用存储过程的方法】

    疑问:怎样判断存储过程执行之后返回值是否为空. 一.连接oracle数据库 1.需要的jar包:在安装的oracle中就有,所以不需要到官网下载,我的oracle11g下:D:\app\kdyzm\p ...

随机推荐

  1. 移动端&sol;H5关于cursor&colon;pointer导致的问题

    cursor属性规定要显示的光标的类型(形状),该属性定义了鼠标指针放在一个元素边界范围内时所用的光标形状(不过 CSS2.1 没有定义由哪个边界确定这个范围). 不过,这个属性用在PC端没有任何问题 ...

  2. 【QT】C&plus;&plus; GUI Qt4 学习笔记2

    Go To Cell 利用QT Desinger做好界面后加入的代码有 gotocelldialog.h #ifndef GOTOCELLDIALOG_H #define GOTOCELLDIALOG ...

  3. Cross-site Scripting &lpar;XSS&rpar; 阅读笔记

    本文源自 https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29 通过阅读和翻译,并按照自己的理解,整理成如下文档. 概述 XSS ...

  4. linux bash&colon; sqlplus&colon; command not found 错误处理

    在oracle用户下 ,执行sqlplus命令,抛出如上错误.   解决办法:   1.su oracle   2.cd /home/oracle   3. 执行命令 source .bash_pro ...

  5. poj题目必做

    OJ上的一些水题(可用来练手和增加自信) (poj3299T,poj2159T,poj2739T,poj1083T,poj2262T,poj1503T,poj3006T,poj2255T,poj309 ...

  6. Gvim for php 安装配置

    VIM for PHP Windows 2011-05-14 11:51:51|  分类: Php|举报|字号 订阅     虽然vim本质上只是一个编辑器.但只要配合一些适当的插件,vim也能变成一 ...

  7. memset与NULL区别

    memset与NULL区别 NULL与0 的区别 为什么强调一个malloc对应一个free 在一个结构体malloc,然后free,但是她的成员变量的malloc并没有free,还需要特别的free ...

  8. GitHub 简易使用

    笔记内容 学习笔记-段玉磊 Github Github 命令 写这篇文章主要写一下如何运用终端命令,进行Git的配置以及使用,由于本人我不太习惯使用图形IDE,效率没有命令行高,我还是推荐使用命令行进 ...

  9. 查全率&lpar;召回率&rpar;、精度(准确率)和F值

    文献中的recall rate(查全率或召回率) and precision(精度)是很重要的概念.可惜很多中文网站讲的我都稀里糊涂,只好用google查了个英文的,草翻如下:召回率和精度定义: 从一 ...

  10. &commat;component &commat;bean区别

    from: http://*.com/questions/10604298/spring-component-versus-bean http://*. ...