使用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服务。

