Trang chủHướng dẫnTạo SOAP web service trong Java bằng Eclipse IDE – có ví dụ minh họa
Chuyên gia

Tạo SOAP web service trong Java bằng Eclipse IDE – có ví dụ minh họa

CyStack blog 10 phút để đọc
CyStack blog11/08/2025
Locker Avatar

Chris Pham

Technical Writer

Locker logo social
Reading Time: 10 minutes

SOAP web service trong Java có thể được phát triển theo nhiều cách khác nhau. Trong bài viết này, chúng ta sẽ học cách tạo SOAP web service và chương trình client tương ứng bằng Eclipse.

Chúng ta sẽ không sử dụng JAX-WS mà thay vào đó là Apache Axis, đây là công cụ được tích hợp sẵn trong Eclipse, giúp chuyển đổi ứng dụng Java thành Web Service một cách nhanh chóng và dễ dàng, đồng thời tạo ra các client stub cùng với trang JSP để kiểm thử.

Tạo SOAP web service trong Java

SOAP Web service trong Java

Tôi đang sử dụng Eclipse Mars Release (4.5.0) cho bài hướng dẫn này, tuy nhiên các bước thực hiện cũng có thể áp dụng cho các phiên bản cũ hơn của Eclipse. Ngoài ra, chúng ta cần đảm bảo Apache Tomcat hoặc bất kỳ servlet container nào khác đã được thêm vào Eclipse dưới dạng máy chủ. Bây giờ, chúng ta sẽ bắt đầu triển khai Web Service bằng Eclipse.

Ví dụ về SOAP Web Service

Chúng ta sẽ bắt đầu với ví dụ về dịch vụ web SOAP trong Eclipse. Trước tiên, chúng ta sẽ tạo một dự án Dynamic Web Project đơn giản trong Eclipse, nơi sẽ chứa phần logic nghiệp vụ của ứng dụng.

SOAP Web Service

Nhấn nút Next ở trên và bạn sẽ được chuyển đến trang tiếp theo để nhập tên dự án web và chỉ định môi trường thực thi (Target Runtime). Ở đây tôi sử dụng Apache Tomcat 8, tuy nhiên bạn có thể sử dụng bất kỳ servlet container tiêu chuẩn nào khác.

SOAP Web Service

Tiếp tục nhấn Next, bạn sẽ được yêu cầu cung cấp “Context Root” và vị trí thư mục nội dung. Có thể giữ nguyên các giá trị mặc định.

SOAP Web Service

Nhấn Finish và Eclipse sẽ tạo khung dự án cho bạn. Bây giờ, chúng ta sẽ bắt đầu với phần logic nghiệp vụ. Trong ví dụ này, chúng ta muốn công bố một web service có khả năng thêm, xóa và truy xuất một đối tượng. Vậy bước đầu tiên là tạo một lớp model bean.

package com.journaldev.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;
	}

}

Lưu ý, lớp trên là một Java Bean đơn giản. Chúng ta triển khai interface Serializable vì đối tượng này sẽ được truyền qua mạng. Ngoài ra, phương thức toString cũng được cài đặt nhằm phục vụ cho việc in ra đối tượng này ở phía client.

Tiếp theo, chúng ta sẽ tạo lớp dịch vụ, bao gồm một interface tên là PersonService và một lớp triển khai đơn giản là PersonServiceImpl.

package com.journaldev.jaxws.service;

import com.journaldev.jaxws.beans.Person;

public interface PersonService {

	public boolean addPerson(Person p);

	public boolean deletePerson(int id);

	public Person getPerson(int id);

	public Person[] getAllPersons();
}

Dưới đây là lớp triển khai interface dịch vụ. Ở đây, chúng ta sử dụng Map để lưu trữ các đối tượng Person như một nguồn dữ liệu. Trong lập trình thực tế, thông tin này thường sẽ được lưu trữ trong cơ sở dữ liệu.

package com.journaldev.jaxws.service;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.journaldev.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;
	}

}

Đó là toàn bộ phần logic nghiệp vụ. Do các lớp này sẽ được sử dụng trong dịch vụ web nên không cần tạo giao diện web tại đây. Lưu ý, trong đoạn mã trên hoàn toàn không có bất kỳ tham chiếu nào đến các lớp liên quan đến dịch vụ web.

SOAP Web service trong Java bằng Eclipse

Khi logic nghiệp vụ đã sẵn sàng, bước tiếp theo là sử dụng Eclipse để tạo ứng dụng dịch vụ web từ phần mã này. Bạn hãy tạo một dự án mới và chọn wizard Web Service.

SOAP Web Service

Nhấn nút Next và bạn sẽ đến trang yêu cầu cung cấp thông tin dịch vụ web và client tương ứng. Đây là bước quan trọng nhất trong quá trình tạo dịch vụ web. Bạn phải chọn “Bottom up Java bean Web Service” trong phần “Web Service type” vì chúng ta đang thực hiện theo phương pháp bottom-up.

Có hai phương pháp tạo web service như sau:

  1. Contract last hay phương pháp Bottom-up: Trong phương pháp này, chúng ta tạo phần triển khai trước rồi mới tạo ra file WSDL từ phần mã đó. Triển khai hiện tại thuộc loại này.
  2. Contract first hay phương pháp Top-down: Trong phương pháp này, file WSDL (tức hợp đồng dịch vụ) được tạo trước, sau đó mới xây dựng phần mã triển khai dựa trên đó.

SOAP Web Service

Trong phần triển khai dịch vụ, chúng ta cần cung cấp đường dẫn đầy đủ đến lớp PersonServiceImpl. Bạn hãy di chuyển thanh trượt về phía bên trái ở phần cấu hình service và client để hệ thống tạo tự động chương trình client cũng như giao diện kiểm thử web service.

Kiểm tra các thiết lập trong phần triển khai dịch vụ web, bạn cần đảm bảo thông tin chi tiết về Server runtime, Web service runtime và service project đều chính xác. Thông thường, các giá trị này sẽ được điền tự động và không cần thay đổi gì thêm.

Đối với phần cấu hình client, bạn có thể đặt tên dự án tùy ý. Trong ví dụ này, tôi giữ nguyên mặc định là SOAPExampleClient. Nếu bạn nhấn vào liên kết của phần Web service runtime, sẽ có nhiều tùy chọn hiện ra như trong hình minh họa. Tuy nhiên, tôi vẫn giữ nguyên thiết lập mặc định.

SOAP Web Service

Nhấn nút Next và bạn sẽ có thể chọn các phương thức mà bạn muốn công bố dưới dạng dịch vụ web. Đồng thời, bạn cũng có thể chọn kiểu dịch vụ web là document hay literal. Bạn có thể thay đổi tên tài liệu WSDL, tuy nhiên nên để tên giống với lớp triển khai để tránh nhầm lẫn sau này.

SOAP Web Service

Nhấn nút Next, bạn sẽ đến trang khởi động máy chủ. Nhấn nút “Start server” để khởi động, sau đó nút Next sẽ được kích hoạt.

SOAP Web Service

Tiếp tục nhấn Next để chuyển đến trang khởi động “Web Services Explorer”.

SOAP Web Service

Nhấn nút Launch để mở ra cửa sổ mới trong trình duyệt, tại đó bạn có thể kiểm thử dịch vụ web trước khi tiến hành xây dựng phần ứng dụng client. Giao diện sẽ giống như hình minh họa đối với dự án của chúng ta.

SOAP Web Service

Tại đây, bạn có thể thực hiện một số kiểm thử cơ bản. Tuy nhiên, đối với ứng dụng đơn giản này, tôi sẽ tiếp tục với phần tạo ứng dụng client. Nhấn nút Next trong cửa sổ bật lên của Eclipse Web Services, bạn sẽ đến trang xác định thư mục nguồn cho ứng dụng client.

SOAP Web Service

Hãy bấm nút Next, sau đó bạn sẽ thấy một loạt tùy chọn để lựa chọn phương thức kiểm thử. Ở đây, tôi chọn JAX-RPC JSPs nhằm để ứng dụng client tạo ra một trang JSP phục vụ cho việc kiểm thử.

SOAP Web Service

Lưu ý, các phương thức getEndpoint()setEndpoint(String) sẽ được tự động thêm vào. Bạn có thể sử dụng chúng để lấy URL endpoint của dịch vụ web và thiết lập URL mới trong trường hợp di chuyển máy chủ sang URL endpoint khác.

Nhấn nút Finish và Eclipse sẽ tạo dự án client trong workspace của bạn, đồng thời khởi động trang JSP kiểm thử client như hình bên dưới.

SOAP Web Service

Bạn có thể sao chép URL và mở nó bằng bất kỳ trình duyệt nào. Hãy thử một số dịch vụ mà chúng ta đã công bố và xem kết quả trả về.

Kiểm thử SOAP Web Service trong Eclipse

addPerson

SOAP Web Service

getPerson

SOAP Web Service

getAllPersons

SOAP Web Service

Lưu ý, thông tin đối tượng Person không được hiển thị trong phần kết quả. Lý do là vì mã này là code tự động tạo và cần được tinh chỉnh một chút để hiển thị đúng kết quả mong muốn. Mở tệp Result.jsp trong dự án client, bạn sẽ thấy trang này sử dụng cấu trúc switch case để tạo kết quả trả về. Đối với phương thức getAllPersons(), trong trường hợp của tôi là case 42. Tuy nhiên, trong dự án của bạn có thể là một giá trị khác.

Tôi đã thay đổi đoạn mã trong case 42 như sau:

case 42:
        gotMethod = true;
        com.journaldev.jaxws.beans.Person[] getAllPersons42mtemp = samplePersonServiceImplProxyid.getAllPersons();
if(getAllPersons42mtemp == null){
%>
<%=getAllPersons42mtemp %>
<%
}else{
        String tempreturnp43 = null;
        if(getAllPersons42mtemp != null){
        java.util.List<com.journaldev.jaxws.beans.Person> listreturnp43= java.util.Arrays.asList(getAllPersons42mtemp);
        //tempreturnp43 = listreturnp43.toString();
        for(com.journaldev.jaxws.beans.Person p : listreturnp43){
        	int id = p.getId();
        	int age = p.getAge();
        	String name=p.getName();
        	%>
        	<%=id%>::<%=name %>::<%=age %>
        	<%
        	}
        }
        }
break;

Sau khi chỉnh sửa, kết quả hiển thị như hình dưới. Lưu ý, Eclipse sử dụng cơ chế triển khai nóng (hot deployment), vì vậy tôi không cần triển khai lại toàn bộ ứng dụng.

SOAP Web Service

Như vậy, chúng ta có thể xác nhận rằng cả ứng dụng dịch vụ web lẫn ứng dụng client đều đang vận hành ổn định. Bạn nên dành thời gian xem xét cẩn thận phần mã stub phía client do Eclipse sinh ra để nắm rõ hơn cách thức hoạt động của hệ thống.

WSDL và cấu hình SOAP Web Service

Cuối cùng, bạn sẽ thấy, tệp WSDL đã được sinh ra trong dự án dịch vụ web. Dưới đây là nội dung tệp PersonServiceImpl.wsdl:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="<https://service.jaxws.journaldev.com>" xmlns:apachesoap="<https://xml.apache.org/xml-soap>" xmlns:impl="<https://service.jaxws.journaldev.com>" xmlns:intf="<https://service.jaxws.journaldev.com>" xmlns:tns1="<https://beans.jaxws.journaldev.com>" 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.journaldev.com>" xmlns="<https://www.w3.org/2001/XMLSchema>">
   <import namespace="<https://beans.jaxws.journaldev.com>"/>
   <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.journaldev.com>" 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>

Nếu bạn mở tệp này bằng chế độ thiết kế trong Eclipse, giao diện sẽ giống như hình minh họa.

SOAP Web Service

Bạn cũng có thể truy cập tệp WSDL của dịch vụ web qua trình duyệt bằng cách thêm hậu tố ?wsdl vào địa chỉ endpoint của dịch vụ.

SOAP Web Service

Bạn cũng sẽ thấy, tệp web.xml đã được chỉnh sửa để sử dụng Apache Axis làm front controller cho dịch vụ web.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="<https://www.w3.org/2001/XMLSchema-instance>" xmlns="<https://xmlns.jcp.org/xml/ns/javaee>" xsi:schemaLocation="<https://xmlns.jcp.org/xml/ns/javaee> <https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd>" id="WebApp_ID" version="3.1">
  <display-name>SOAPExample</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <display-name>Apache-Axis Servlet</display-name>
    <servlet-name>AxisServlet</servlet-name>
    <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/servlet/AxisServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>*.jws</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>
  <servlet>
    <display-name>Axis Admin Servlet</display-name>
    <servlet-name>AdminServlet</servlet-name>
    <servlet-class>org.apache.axis.transport.http.AdminServlet</servlet-class>
    <load-on-startup>100</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>AdminServlet</servlet-name>
    <url-pattern>/servlet/AdminServlet</url-pattern>
  </servlet-mapping>
</web-app>

Hình ảnh bên dưới minh họa cho cấu trúc dự án dịch vụ web và client với toàn bộ các stub và trang JSP được được tạo tự động để kiểm thử dịch vụ web.

SOAP Web Service

SOAP Web Service

Đó là toàn bộ nội dung ví dụ về SOAP Web service trong Java sử dụng Eclipse. Như bạn thấy, hầu hết các phần phức tạp đã được Eclipse tự động xử lý và công việc chính của chúng ta chỉ là viết phần logic nghiệp vụ cho dịch vụ web.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất