关于java:来自Javascript的SOAP Web服务调用

SOAP web service calls from Javascript

我正在努力成功地从网页上调用SOAP Web服务。 Web服务是使用JAX-WS的Java Web服务。

这是我试图调用的Web方法:

1
2
3
4
5
6
@WebMethod  
public String sayHi(@WebParam(name="name") String name)  
{  
    System.out.println("Hello"+name+"!");  
    return"Hello"+name+"!";  
}

我尝试使用JQuery库jqSOAPClient(http://plugins.jquery.com/project/jqSOAPClient)进行Web服务调用。
这是我用过的代码:

1
2
3
4
5
6
7
8
9
10
11
12
var processResponse = function(respObj)  
{  
    alert("Response received:"+respObj);  
};

SOAPClient.Proxy = url;  
var body = new SOAPObject("sayHi");  
body.ns = ns;  
body.appendChild(new SOAPObject("name").val("Bernhard"));

var sr = new SOAPRequest(ns+"sayHi",body);  
SOAPClient.SendRequest(sr,processResponse);

似乎没有回应。当在jqSOAPClient.js中我记录xData.responseXML数据成员时,我得到'未定义'。在Web服务中,我看到了警告

24 Mar 2011 10:49:51 AM com.sun.xml.ws.transport.http.server.WSHttpHandler handleExchange
WARNING: Cannot handle HTTP method: OPTIONS

我也尝试过使用javascript库soapclient.js(http://www.codeproject.com/kb/Ajax/JavaScriptSOAPClient.aspx)。我在这里使用的客户端代码是

1
2
3
4
5
6
7
8
var processResponse = function(respObj)
{
    alert("Response received:"+respObj);
};

var paramaters = new SOAPClientParameters();
paramaters.add("name","Bernhard");
SOAPClient.invoke(url,"sayHi",paramaters,true,processResponse);

我绕过了抓取WSDL的soapclient.js中的部分,因为它不起作用
(我在Web服务端得到了一个:IOException: An established connection was aborted by the software in your host machine)。只检索WSDL以使用适当的名称空间,因此我只是将变量ns替换为实际名称空间。

我在Web服务上获得与以前完全相同的警告(无法处理HTTP方法:OPTIONS),并且在浏览器的错误控制台中,我收到错误"document is null"。当我在soapclient.js中记录req.responseXML的值时,我看到它为null。

任何人都可以建议可能出现的问题以及我应该怎样做才能让它发挥作用?


我发现这里发生了什么。它与此线程中的场景相同:jQuery $ .ajax(),$ .post在Firefox中将"OPTIONS"作为REQUEST_METHOD发送。

基本上我使用Firefox,当一个人使用AJAX从Firefox进行跨域调用(Web服务的地址域与网页的域名不同)时,Firefox首先发送一个OPTIONS HTTP消息(在它发送POST消息之前),从Web服务确定是否应该允许呼叫。然后,Web服务必须响应此OPTIONS消息,以告知它是否允许请求通过。

现在,来自JAX-WS的警告("无法处理HTTP方法:OPTIONS")表明它不会处理任何OPTIONS HTTP消息。没关系 - Web服务最终将在Glassfish上运行。
现在的问题是如何配置Glassfish来响应OPTIONS消息。

在上面引用的主题中,Juha说他在Django中使用以下代码:

1
2
3
4
5
6
7
8
9
10
def send_data(request):  
    if request.method =="OPTIONS":  
        response = HttpResponse()  
        response['Access-Control-Allow-Origin'] = '*'  
        response['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'  
        response['Access-Control-Max-Age'] = 1000  
        response['Access-Control-Allow-Headers'] = '*'  
        return response  
    if request.method =="POST":  
        # ...

Access-Control-Allow-Origin提供了一个模式,指示将接受哪些来源(收件人地址)(我的可能比简单地允许任何来源更严格)和Access-Control-Max-Age告诉客户端多少秒必须再次申请许可。

我如何在Glassfish中执行此操作?


你真的测试过ws工作正常吗?
您可以使用SoapUI检查请求/响应等。
当您确认ws正在使用SoapUI时,请检查原始Soap消息的格式。然后尝试在使用.js方法发送之前检查它的外观,并比较它们。

它可能会帮助您理解错误。


检查这是否有帮助
http://bugs.jquery.com/attachment/ticket/6029/jquery-disable-firefox3-cross-domain-magic.patch

它被标记为无效
http://bugs.jquery.com/ticket/6029
但它可能会给你一些提示

另一方面,如果您可以创建并调用将请求ws并返回结果的本地页面,则可以更好地覆盖跨域脚本的正确设置。
或者甚至更好,您可以创建将接收url作为参数的页面,并请求该URL并返回结果。这样它将更通用和可重用。