通过soap利用ajax调用WebService主要是为了解决不同的平台之间的服务通讯或者数据交换,但是如果在不同的域环境中,每次调用的时候会弹出警告框,要想不每次都弹出警告框,只能手动设置浏览器选项,在项目发布后,去为每个用户设置一下会很麻烦。还有就是有时候会出现图片所显示XMLHttpRequest的Access-Control-Allow-Origin问题。所以,解决方法就是通过json的传送数据来代替soap消息的传送。这有点类似于调用网上的web服务接口然后返回json消息,如查询天气。本文使用servlet和jsonp方式模拟soap
(soap调用webservice代码如下,仅供对比
<html> <head> <!--<meta http-equiv="Access-Control-Allow-Origin" content="*">--> <title>通过ajax调用WebService服务</title> <script> var xhr = new XMLHttpRequest(); function sendMsg(){ // alert("sasdasd") var name = document.getElementById('name').value; //服务的地址 var wsUrl = 'http://localhost:9000/HelloWorld'; // var wsUrl= "http://example/HelloWorldService"; var soap = '<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://example/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + " <soapenv:Body><q0:sayHelloWorldFrom><arg0>"+name+"</arg0></q0:sayHelloWorldFrom></soapenv:Body></soapenv:Envelope>"; alert(soap) //打开连接 xhr.open('POST',wsUrl,true); //重新设置请求头 xhr.setRequestHeader("Content-Type","text/xml;charset=UTF-8"); //设置回调函数 // xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded") // xhr.setRequestHeader("Content-type", "Access-Control-Allow-Origin: POST") xhr.onreadystatechange = _back; //发送请求 xhr.send(soap); } function _back(){ if(xhr.readyState == 4){ alert(xhr.status) if(xhr.status == 200){ alert('调用Webservice成功了'); var ret = xhr.responseXML; var msg = ret.getElementsByTagName('return')[0]; document.getElementById('showInfo').innerHTML = msg.text; //alert(msg.text); } } } </script> </head> <body> <input type="button" value="发送SOAP请求" οnclick="sendMsg();"> <input type="text" id="name"> <div id="showInfo"> </div> </body> </html>
)
由于整个过程不需要webservice了,所以就不需要再编写webservice的方法,只需要普通的方法就可以实现不同平台的数据的传输。
首先,在idea14.04中利用servlet来模拟原先的soap地址的访问。新建一个web项目
然后新建一个servlet用来模拟soap访问url。代码如下:
import net.sf.json.JSONObject; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; /** * Created by tengqingya-njupt on 2015/8/26. */ public class Servlet extends javax.servlet.http.HttpServlet { protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { doGet(request,response); } protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { response.setContentType("text/plain"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); // Map<String, int[]> map = new HashMap<String, int[]>(); Map<String, String> map = new HashMap<String, String>(); PrintWriter out = response.getWriter(); map.put("result", request.getParameter("name")); // int a[]={1,2,3}; //这里可以在接受到客户端传过来的参数result后,调用服务器端的业务代码,然后把数据封装到map中,再封装到json中 map.put("Class","Main"); //将结果组装成json JSONObject resultJSON = JSONObject.fromObject(map); String jsonpCallback = request.getParameter("jsonpCallback");//客户端请求参数 out.println(jsonpCallback+"("+resultJSON.toString(1,1)+")");//返回jsonp格式数据 out.flush(); out.close(); } }别忘了配置servlet映射关系:
在web.xml中:
如果修改 data.Class为data.result.结果如下<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <servlet> <servlet-name>Servlet</servlet-name> <servlet-class>Servlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet</servlet-name> <url-pattern>/tqy</url-pattern> </servlet-mapping> </web-app>以上配置说明通过http://localhost:8080/tqy地址就可以访问我们写的Servlet代码了。启动tomcat服务器(如果第一次使用idea或者之间没有配置过tomcat可以按照下图配置:在文件->设置(setting)->输入server->加号,add一个服务器)。然后就是启动,可以在index.jsp文件上右击鼠标run,然后在浏览器中输入http://localhost:8080/tqy。效果如下:
。这样服务器端的“webservice”就开发好了。下面开始客户端网页的开发。
使用idea新建一个static web项目。再新建一个html文件名为test。代码如下:<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="jquery.js"></script> </head> <script type="text/javascript"> $(function(){ $.ajax({ type : "get", async:false, url : "http://192.168.11.113:8080/tqy?name='tqy'",//传参到服务器模拟WS方法传参 dataType : "jsonp",//数据类型为jsonp jsonp: "jsonpCallback",//服务端用于接收callback调用的function名的参数 success : function(data){ $("#showcontent").text("Result:"+data.Class) }, error:function(){ alert('fail'); } }); }); </script> <body> <div id="showcontent">Result:</div> </body> </html>以上代码中data里面存放的就是json格式的数据,比如之前Class里面放的是Main,那么data.Class的值就是Main。效果图如下:![]()
到此。模拟soap调用webservice的过程就大功告成。这样,原先通过soap调用webservice返回的数据,就可以用servlet返回json数据代替实现了。也是跨平台调用。