使用Eclipse的Java示例中的SOAP Web服务

时间:2020-02-23 14:35:35  来源:igfitidea点击:

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