使用Eclipse的Java示例中的SOAP Web服务
Java中的Soap Webservices可以通过多种方式开发。
我们在上一教程中了解了JAX-WS SOAP Web服务,今天我们将学习如何使用Eclipse创建SOAP Web服务及其客户端程序。
其中我们将不使用JAX-WS,而是将使用集成在Eclipse中的Apache Axis,它提供了快速简便的方法来将应用程序转换为Java Web Service并创建带有测试JSP页面的客户端存根以进行测试。
Java中的SOAP Web服务
我在本教程中使用的是Eclipse Mars Release(4.5.0),但我认为这些步骤也适用于旧版本的eclipse。
还要确保已将Apache Tomcat或者任何其他servlet容器添加为Eclipse中的服务器。
现在让我们从Eclipse Web Service实施开始。
SOAP Web服务示例
让我们开始使用Eclipse中的SOAP网络服务示例。
首先,我们将在Eclipse中创建一个简单的Dynamic Web Project,其中将包含应用程序的业务逻辑。
单击上方的下一步按钮,您将获得下一页,以提供您的Web项目名称和目标运行时。
注意,我正在使用Apache Tomcat 8,您也可以使用任何其他标准servlet容器。
单击下一步,将要求您提供"上下文根"和内容目录位置。
您可以将它们保留为默认值。
单击Finish,Eclipse将为您创建项目框架。
让我们开始我们的业务逻辑。
因此,对于我们的示例,我们想发布一个可用于添加/删除/获取对象的Web服务。
因此,第一步是创建模型bean。
package com.theitroad.jaxws.beans; import java.io.Serializable; public class Person implements Serializable{ private static final long serialVersionUID = -5577579081118070434L; private String name; private int age; private int id; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString(){ return id+"::"+name+"::"+age; } }
注意,上面是一个简单的Java bean,我们正在实现Serializable
接口,因为我们将通过网络进行传输。
我们还提供了toString
方法的实现,将在客户端打印该对象时使用。
下一步是创建服务类,因此我们将有一个接口" PersonService"和简单的实现类" PersonServiceImpl"。
package com.theitroad.jaxws.service; import com.theitroad.jaxws.beans.Person; public interface PersonService { public boolean addPerson(Person p); public boolean deletePerson(int id); public Person getPerson(int id); public Person[] getAllPersons(); }
下面是实现服务类,我们使用Map将Person对象存储为数据源。
在现实世界的编程中,我们希望将它们保存到数据库表中。
package com.theitroad.jaxws.service; import java.util.HashMap; import java.util.Map; import java.util.Set; import com.theitroad.jaxws.beans.Person; public class PersonServiceImpl implements PersonService { private static Map<Integer,Person> persons = new HashMap<Integer,Person>(); @Override public boolean addPerson(Person p) { if(persons.get(p.getId()) != null) return false; persons.put(p.getId(), p); return true; } @Override public boolean deletePerson(int id) { if(persons.get(id) == null) return false; persons.remove(id); return true; } @Override public Person getPerson(int id) { return persons.get(id); } @Override public Person[] getAllPersons() { Set<Integer> ids = persons.keySet(); Person[] p = new Person[ids.size()]; int i=0; for(Integer id : ids){ p[i] = persons.get(id); i++; } return p; } }
就我们的业务逻辑而言,就是这样,因为我们将在Web服务中使用它们,所以这里没有必要创建网页。
注意,上面的代码中没有引用任何类型的Web服务类。
使用Eclipse的Java中的SOAP Web服务
一旦我们的业务逻辑准备就绪,下一步就是使用Eclipse从中创建Web服务应用程序。
创建一个新项目,然后选择Web服务向导。
点击下一步按钮,您将获得一个页面,其中必须提供网络服务及其客户详细信息。
这是创建Web服务时最重要的页面。
确保选择" Web服务类型"作为"自下而上的Java bean Web服务",因为我们采用的是自下而上的方法。
有两种创建Web服务的方法:
契约最后或者自下而上的方法:在这种方法中,我们首先创建实现,然后从中生成WSDL文件。
我们的实现属于此类。合同优先或者自上而下的方法:在这种方法中,我们首先创建Web服务合同,即WSDL文件,然后为其创建实现。
在服务实现中,提供实现类PersonServiceImpl
的完全分类路径。
确保将服务和客户端类型中的滑块移到左侧,以便它可以生成客户端程序以及用于测试我们的Web服务的UI。
检查Web服务实现中的配置,您应该提供服务器运行时,Web服务运行时和服务项目的正确详细信息。
通常,它们是自动填充的,您无需在此处进行任何更改。
对于客户端配置,您可以根据需要提供客户端项目名称。
我将其默认设置为SOAPExampleClient。
如果您单击Web服务运行时的链接,则将获得不同的选项,如下图所示。
但是,我将其保留为默认值。
单击下一步按钮,然后您将能够选择要作为Web服务公开的方法。
您还可以选择Web服务样式为文档还是文字。
您可以更改WSDL文档名称,但最好将它与实现类名称一起使用,以免日后造成混淆。
单击下一步按钮,您将获得服务器启动页面,单击"启动服务器"按钮,然后将启用下一步按钮。
单击下一步按钮,您将获得一个页面以启动" Web Services Explorer"。
单击启动按钮,它将在浏览器中打开一个新窗口,您可以在继续客户端应用程序部分之前测试Web服务。
看起来像我们项目的下图。
我们可以在此处进行一些健全性测试,但是对于我们的简单应用程序,我准备继续进行客户端应用程序的创建。
在Eclipse Web服务弹出窗口中单击"下一步"按钮,您将获得一个用于客户机应用程序的源文件夹的页面。
单击下一步按钮,您将获得不同的选项以选择作为测试工具。
我将继续使用JAX-RPC JSP,以便客户端应用程序将生成我们可以使用的JSP页面。
注意,添加了方法getgetpoint()和setEndpoint(String),我们可以使用它们来获取Web服务端点URL,并且可以将其设置为其他URL,以防我们将服务器移至其他URL端点。
单击Finish按钮,Eclipse将在您的工作区中创建客户机项目,它还将启动客户机测试JSP页面,如下所示。
您可以复制URL并在所需的任何浏览器中打开。
让我们测试一下我们已经公开的一些服务并查看输出。
Eclipse SOAP Web服务测试
- addPerson
- getPerson
- getAllPersons
注意,Person的详细信息没有打印在结果部分中,这是因为它是自动生成的代码,我们需要对其进行一些重构以获取所需的输出。
在客户端项目中打开Result.jsp,您将看到它使用了case切换生成结果输出。
对于getAllPersons()方法,在我的案例中是案例42。
请注意,您的情况可能会完全不同。
我只是更改了案例42的代码,如下所示。
之后,我们得到下面的输出,请注意,Eclipse在这里进行热部署,因此我不必重新部署应用程序。
因此,看来我们的Web服务和客户端应用程序运行良好,请确保花一些时间查看Eclipse生成的客户端存根以了解更多信息。
SOAP Web服务WSDL和配置
最后,您将注意到在Web服务项目中生成了WSDL文件,如下所示。
PersonServiceImpl.wsdl代码:
case 42: gotMethod = true; com.theitroad.jaxws.beans.Person[] getAllPersons42mtemp = samplePersonServiceImplProxyid.getAllPersons(); if(getAllPersons42mtemp == null){ %> <%=getAllPersons42mtemp %> <% }else{ String tempreturnp43 = null; if(getAllPersons42mtemp != null){ java.util.List<com.theitroad.jaxws.beans.Person> listreturnp43= java.util.Arrays.asList(getAllPersons42mtemp); //tempreturnp43 = listreturnp43.toString(); for(com.theitroad.jaxws.beans.Person p : listreturnp43){ int id = p.getId(); int age = p.getAge(); String name=p.getName(); %> <%=id%>::<%=name %>::<%=age %> <% } } } break;
如果要在Eclipse中以设计方式打开它,它将看起来像下面的图像。
您还可以通过将?wsdl附加到Web服务端点来通过浏览器访问Web服务WSDL文件。
您还将注意到,将web.xml修改为使用Apache Axis作为Web服务的前端控制器。
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="https://service.jaxws.theitroad.local" xmlns:apachesoap="https://xml.apache.org/xml-soap" xmlns:impl="https://service.jaxws.theitroad.local" xmlns:intf="https://service.jaxws.theitroad.local" xmlns:tns1="https://beans.jaxws.theitroad.local" xmlns:wsdl="https://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="https://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="https://www.w3.org/2001/XMLSchema"> <!--WSDL created by Apache Axis version: 1.4 Built on Apr 22, 2006 (06:55:48 PDT)--> <wsdl:types> <schema elementFormDefault="qualified" targetNamespace="https://service.jaxws.theitroad.local" xmlns="https://www.w3.org/2001/XMLSchema"> <import namespace="https://beans.jaxws.theitroad.local" <element name="addPerson"> <complexType> <sequence> <element name="p" type="tns1:Person" </sequence> </complexType> </element> <element name="addPersonResponse"> <complexType> <sequence> <element name="addPersonReturn" type="xsd:boolean" </sequence> </complexType> </element> <element name="deletePerson"> <complexType> <sequence> <element name="id" type="xsd:int" </sequence> </complexType> </element> <element name="deletePersonResponse"> <complexType> <sequence> <element name="deletePersonReturn" type="xsd:boolean" </sequence> </complexType> </element> <element name="getPerson"> <complexType> <sequence> <element name="id" type="xsd:int" </sequence> </complexType> </element> <element name="getPersonResponse"> <complexType> <sequence> <element name="getPersonReturn" type="tns1:Person" </sequence> </complexType> </element> <element name="getAllPersons"> <complexType </element> <element name="getAllPersonsResponse"> <complexType> <sequence> <element maxOccurs="unbounded" name="getAllPersonsReturn" type="tns1:Person" </sequence> </complexType> </element> </schema> <schema elementFormDefault="qualified" targetNamespace="https://beans.jaxws.theitroad.local" xmlns="https://www.w3.org/2001/XMLSchema"> <complexType name="Person"> <sequence> <element name="age" type="xsd:int" <element name="id" type="xsd:int" <element name="name" nillable="true" type="xsd:string" </sequence> </complexType> </schema> </wsdl:types> <wsdl:message name="addPersonResponse"> <wsdl:part element="impl:addPersonResponse" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="getAllPersonsResponse"> <wsdl:part element="impl:getAllPersonsResponse" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="deletePersonResponse"> <wsdl:part element="impl:deletePersonResponse" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="addPersonRequest"> <wsdl:part element="impl:addPerson" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="getPersonResponse"> <wsdl:part element="impl:getPersonResponse" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="getPersonRequest"> <wsdl:part element="impl:getPerson" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="deletePersonRequest"> <wsdl:part element="impl:deletePerson" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="getAllPersonsRequest"> <wsdl:part element="impl:getAllPersons" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:portType name="PersonServiceImpl"> <wsdl:operation name="addPerson"> <wsdl:input message="impl:addPersonRequest" name="addPersonRequest"> </wsdl:input> <wsdl:output message="impl:addPersonResponse" name="addPersonResponse"> </wsdl:output> </wsdl:operation> <wsdl:operation name="deletePerson"> <wsdl:input message="impl:deletePersonRequest" name="deletePersonRequest"> </wsdl:input> <wsdl:output message="impl:deletePersonResponse" name="deletePersonResponse"> </wsdl:output> </wsdl:operation> <wsdl:operation name="getPerson"> <wsdl:input message="impl:getPersonRequest" name="getPersonRequest"> </wsdl:input> <wsdl:output message="impl:getPersonResponse" name="getPersonResponse"> </wsdl:output> </wsdl:operation> <wsdl:operation name="getAllPersons"> <wsdl:input message="impl:getAllPersonsRequest" name="getAllPersonsRequest"> </wsdl:input> <wsdl:output message="impl:getAllPersonsResponse" name="getAllPersonsResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="PersonServiceImplSoapBinding" type="impl:PersonServiceImpl"> <wsdlsoap:binding style="document" transport="https://schemas.xmlsoap.org/soap/http" <wsdl:operation name="addPerson"> <wsdlsoap:operation soapAction="" <wsdl:input name="addPersonRequest"> <wsdlsoap:body use="literal" </wsdl:input> <wsdl:output name="addPersonResponse"> <wsdlsoap:body use="literal" </wsdl:output> </wsdl:operation> <wsdl:operation name="deletePerson"> <wsdlsoap:operation soapAction="" <wsdl:input name="deletePersonRequest"> <wsdlsoap:body use="literal" </wsdl:input> <wsdl:output name="deletePersonResponse"> <wsdlsoap:body use="literal" </wsdl:output> </wsdl:operation> <wsdl:operation name="getPerson"> <wsdlsoap:operation soapAction="" <wsdl:input name="getPersonRequest"> <wsdlsoap:body use="literal" </wsdl:input> <wsdl:output name="getPersonResponse"> <wsdlsoap:body use="literal" </wsdl:output> </wsdl:operation> <wsdl:operation name="getAllPersons"> <wsdlsoap:operation soapAction="" <wsdl:input name="getAllPersonsRequest"> <wsdlsoap:body use="literal" </wsdl:input> <wsdl:output name="getAllPersonsResponse"> <wsdlsoap:body use="literal" </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="PersonServiceImplService"> <wsdl:port binding="impl:PersonServiceImplSoapBinding" name="PersonServiceImpl"> <wsdlsoap:address location="https://localhost:8080/SOAPExample/services/PersonServiceImpl" </wsdl:port> </wsdl:service> </wsdl:definitions>
下图显示了Web服务和客户端项目,以及所有自动生成的存根和JSP页面来测试Web服务。