来自Javascript的SOAP Web服务调用

时间:2011-03-24 09:22:00

标签: java javascript jquery soap jax-ws

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

以下是我要调用的网络方法:

@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服务调用。
这是我用过的代码:

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服务中,我看到了警告

  

2011年3月24日上午10:49:51 com.sun.xml.ws.transport.http.server.WSHttpHandler handleExchange   警告:无法处理HTTP方法:OPTIONS

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

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中的部分,因为它不起作用 (我在网络服务方面获得了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。

有人可以告知可能出现的问题以及我应该采取什么措施来实现这一目标吗?

3 个答案:

答案 0 :(得分:2)

我发现这里发生了什么。这与此主题中的情况相同:jQuery $.ajax(), $.post sending "OPTIONS" as REQUEST_METHOD in Firefox

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

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

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

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中执行此操作?

答案 1 :(得分:1)

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

这可能有助于您了解错误。

答案 2 :(得分:0)

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

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

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