您的位置:首页 > 编程语言 > ASP

使用ASP等客户端来访问Java的Web Service,取得复杂数据(DTO)

2008-09-26 14:07 543 查看
本文使用ASP.Net的客户端来访问Java写的Web Service。Web Service返回的结果是一个DTO(JavaBean)。

日前看到很多朋友说用ASP的客户端调用Java写的Web Service返回结果是Null,本文也提供了一些看法,希望对大家有点帮助。

首先说一下机制,这里只涉及最简单的。

首先,传输的协议是Soap,说白了就是使用一个规范的XML文本来进行传输。客户端和WS端都根据规范来解析XML文本,以获得需要的数据。

下面是正文。

下来建立Java的Web Service端。

首先建立一个动态网页工程。

接下来我们建立一个DTO(JavaBean)来充当传输的介质。

代码如下:

package demo;

public class EmployeeDTO {

String name;

String dept;

String age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getDept() {

return dept;

}

public void setDept(String dept) {

this.dept = dept;

}

public String getAge() {

return age;

}

public void setAge(String age) {

this.age = age;

}

}

好了,现在我们来建立一个Web Service程序

代码如下:

package demo;

/**

* Demo Web Service

*

* @author redria

*

*/

public class EmployeeWS {

/**

* Get Employee DTO Info

*

* @return

*/

public EmployeeDTO getInfo() {

//New DTO

EmployeeDTO dto = new EmployeeDTO();

dto.setName("Sol");

dto.setDept("GGXX");

dto.setAge("...?");

//Return Value

return dto;

}

}

现在我们准备好了,可以发布Web Service程序了。使用插件可以很方便的发布服务。这里使用附带WTP的Eclipse附带的工具来发布。



当然,在这里点击下面的生成Client也可以自动帮你生成Client端。因为本文使用ASP来生成客户端,所以这里就不说明Java的了

好了,现在测试一下我们的结果:



可以看到,我们Web Service完全正常。(这里如果不正常,可能是你的环境有问题)

现在我们将其发布到tomcat中去。
访问我们刚才发布的Web Service的wsdl文件。你可以看到:



说明我们的服务已经发布成功了。

现在来建立一个ASP.Net的客户端。
打开Visual Studio
新建一个ASP.Net Web Site工程

首先我们添加一个 Web 参照,将我们刚才发布的地址加入,就可以看到了。



好了,现在我们来添加吧。

之后来写前台的Aspx文件和后台的cs文件

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>無題のページ</title>

</head>

<body>

<form id="form1" runat="server">

<div>

<asp:Button ID="BTN_GETINFO" runat="server" OnClick="BTN_GETINFO_Click" Text="获取信息" /><br />

<br />

<asp:Label ID="LB_NAME" runat="server" Text="Name:"></asp:Label>

<asp:Label ID="LB_NAMERESULT" runat="server"></asp:Label><br />

<asp:Label ID="LB_DEPT" runat="server" Text="Dept:"></asp:Label>

<asp:Label ID="LB_DEPTRESULT" runat="server"></asp:Label><br />

<asp:Label ID="LB_AGE" runat="server" Text="Age:"></asp:Label>

<asp:Label ID="LB_AGERESULT" runat="server"></asp:Label></div>

</form>

</body>

</html>

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

}

protected void BTN_GETINFO_Click(object sender, EventArgs e)

{

//call Web Service

localhost.EmployeeWSService service = new localhost.EmployeeWSService();

localhost.EmployeeDTO dto = service.getInfo();

this.LB_NAMERESULT.Text = dto.name;

this.LB_DEPTRESULT.Text = dto.dept;

this.LB_AGERESULT.Text = dto.age;

}

}

好了,现在来运行看看结果。



好了,看起来,我们已经完全成功了。

接下来我们把Web Service放到Axis2中间来看看。

首先,由于发布的路径不一样我们需要相应的修改Web Service的wsdl文件。

修改address地址如下

<wsdlsoap:address location="http://localhost:8080/axis2/services/EmployeeWSService"/>

好了,现在打包发布吧。使用Axis2官方提供的插件可以很方便发布,这里就不多说了,不懂可以参照我关于ESB(ServiceMix)的那片文章中有提到,或者自己在网上搜搜,相关说明很多。

发布后我们可以在Axis2的Service列表中看到



接下来修改我们再来新建一个Asp的客户端,来看看有什么区别。

我们新建一个Aspx页面。

现在我们将Axis2的服务添加到Web 参照中去。



为了不和前一个Web Service冲突,我们将名字改掉

下面来完成页面

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title>無題のページ</title>

</head>

<body>

<form id="form1" runat="server">

<div>

<h1>使用Axis2的Web Service</h1>

<asp:Button ID="BTN_GETINFO" runat="server" OnClick="BTN_GETINFO_Click" Text="获取信息" /><br />

<br />

<asp:Label ID="LB_NAME" runat="server" Text="Name:"></asp:Label>

<asp:Label ID="LB_NAMERESULT" runat="server"></asp:Label><br />

<asp:Label ID="LB_DEPT" runat="server" Text="Dept:"></asp:Label>

<asp:Label ID="LB_DEPTRESULT" runat="server"></asp:Label><br />

<asp:Label ID="LB_AGE" runat="server" Text="Age:"></asp:Label>

<asp:Label ID="LB_AGERESULT" runat="server"></asp:Label>

</div>

</form>

</body>

</html>

using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

public partial class Default2 : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

}

protected void BTN_GETINFO_Click(object sender, EventArgs e)

{

//call Web Service

Axis2.EmployeeWSService service = new Axis2.EmployeeWSService();

Axis2.EmployeeDTO dto = service.getInfo();

this.LB_NAMERESULT.Text = dto.name;

this.LB_DEPTRESULT.Text = dto.dept;

this.LB_AGERESULT.Text = dto.age;

}

}

好了,我们可以看到和前一个没有什么区别,那我们来尝试一下。

结果是,一点访问WebService,我们的程序就出错了,因为WebService的返回结果是null。(相信很多朋友在调用Java发布在各种服务上的WS,都或多或少发生了类似返回为null的问题)

可是我们同样的代码,为什么会有不同的结果?难道问题处在了Axis2上面?

我们可以确信,我们的代码没有错误,因为放在Axis2之前,我们的程序很正常。

然而看看WebService端,好像也没有出错,如果打log,会发现我们其实是成功调用了Web Service,Web Service也正确返回值了,为什么我们在客户端收到的是一个Null值?

要解决这个问题,我们可以尝试分析一下我们到底传输了什么soap。

我们使用一些包截取工具来截取我们传输的信息。

这里本文使用的是 Microsoft SOAP Toolkit Version 3 ,当然是用其它工具也行。

现在我们来分别截取一下我们两次调用返回的结果吧,看看有什么不同。(这里也可以使用我在关于ESB(ServiceMix)的那片文章中最后测试用的html,那个html就是把发送的soap和返回的soap都显示的网页)

我们第一次成功的返回soap是

<?xml version='1.0' encoding='UTF-8'?>

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<soapenv:Body>

<getInfoResponse xmlns:ns="http://demo">

<getInfoReturn>

<age>...?</age>

<dept>GGXX</dept>

<name>Sol</name>

</getInfoReturn>

</getInfoResponse>

</soapenv:Body>

</soapenv:Envelope>

而我们第二次使用Axis2返回的soap是

<?xml version='1.0' encoding='UTF-8'?>

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

<soapenv:Body>

<ns:getInfoResponse xmlns:ns="http://demo">

<ns:return type="demo.EmployeeDTO">

<ns:age>...?</ns:age>

<ns:dept>GGXX</ns:dept>

<ns:name>Sol</ns:name>

</ns:return>

</ns:getInfoResponse>

</soapenv:Body>

</soapenv:Envelope>

这两个的区别在哪里呢?

<ns:return type="demo.EmployeeDTO">和<getInfoReturn>是区别。

Axis2中的return值不在像以前一样直接写明,而是使用名字为return的量,使用type来定义它的类型。

所以这里我们的接口不一样,就像我们去A码头接人,人却从B码头来了,我们自然什么都没有接到。

找到问题的所在,接下来我们只要修改wsdl中的return接口定义,就可以接到值了。

修改发布到Axis2的WS的wsdl文件

<?xml version="1.0" encoding="UTF-8"?>

<wsdl:definitions targetNamespace="http://demo" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://demo" xmlns:intf="http://demo" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<!--WSDLはApache Axis version: 1.4

Built on Apr 22, 2006 (06:55:48 PDT)によって生成されました / [en]-(WSDL created by Apache Axis version: 1.4

Built on Apr 22, 2006 (06:55:48 PDT))-->

<wsdl:types>

<schema elementFormDefault="qualified" targetNamespace="http://demo" xmlns="http://www.w3.org/2001/XMLSchema">

<element name="getInfo">

<complexType/>

</element>

<element name="getInfoResponse">

<complexType>

<sequence>

<element name="return" type="impl:EmployeeDTO"/>

</sequence>

</complexType>

</element>

<complexType name="EmployeeDTO">

<sequence>

<element name="age" nillable="true" type="xsd:string"/>

<element name="dept" nillable="true" type="xsd:string"/>

<element name="name" nillable="true" type="xsd:string"/>

</sequence>

</complexType>

</schema>

</wsdl:types>

<wsdl:message name="getInfoRequest">

<wsdl:part element="impl:getInfo" name="parameters"/>

</wsdl:message>

<wsdl:message name="getInfoResponse">

<wsdl:part element="impl:getInfoResponse" name="parameters"/>

</wsdl:message>

<wsdl:portType name="EmployeeWS">

<wsdl:operation name="getInfo">

<wsdl:input message="impl:getInfoRequest" name="getInfoRequest"/>

<wsdl:output message="impl:getInfoResponse" name="getInfoResponse"/>

</wsdl:operation>

</wsdl:portType>

<wsdl:binding name="EmployeeWSSoapBinding" type="impl:EmployeeWS">

<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>

<wsdl:operation name="getInfo">

<wsdlsoap:operation soapAction=""/>

<wsdl:input name="getInfoRequest">

<wsdlsoap:body use="literal"/>

</wsdl:input>

<wsdl:output name="getInfoResponse">

<wsdlsoap:body use="literal"/>

</wsdl:output>

</wsdl:operation>

</wsdl:binding>

<wsdl:service name="EmployeeWSService">

<wsdl:port binding="impl:EmployeeWSSoapBinding" name="EmployeeWS">

<wsdlsoap:address location="http://localhost:8080/axis2/services/EmployeeWSService"/>

</wsdl:port>

</wsdl:service>

</wsdl:definitions>

重新发布一下,再来测试我们的第二个客户端,果然成功的取到了值,问题圆满解决了。

注:Java客户端其实和Asp一样会遇到这种问题,问题的本质是一样的。

总结:现在功能强大的工具软件是我们的工作变得非常简单,遇到了这种问题,我们可以从它到底在传输什么着手,做些分析就可以找到问题的所在。尤其像Soap这样的东西,自己动手,丰衣足食么……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐