- Sản phẩm & Dịch vụSản phẩm & Dịch vụ
- Giải phápGiải pháp
- Bảng giáBảng giá
- Công tyCông ty
- Tài liệuTài liệu
vi
vi
Chuyên mục với 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.
Technical Writer
I have over 5 years of experience writing technical documentation for tech products, making them accessible and user-friendly. My focus is always on providing clear and precise information. @#@ Tôi đã có hơn 5 năm kinh nghiệm viết tài liệu kỹ thuật cho các sản phẩm công nghệ, giúp người dùng dễ dàng tiếp cận và sử dụng. Tôi luôn tập trung vào việc cung cấp thông tin chính xác và dễ hiểu.
Thảo luận (0)
Đăng nhập để thảo luận
Bài viết này tổng hợp các câu hỏi phỏng vấn về web service (dịch vụ web). Chúng ta sẽ bắt đầu với những khái niệm tổng quát, không phụ thuộc vào công nghệ hay ngôn ngữ cụ thể nào. Ở phần cuối của bài viết chúng ta sẽ đi sâu vào các câu hỏi dành riêng cho Java web service.

Web service hoạt động theo mô hình client-server (máy khách-máy chủ), cho phép các ứng dụng client truy cập dịch vụ ở trên server qua mạng.
Chúng cung cấp các URL endpoint (điểm truy cập, nơi nhận và xử lý các request) và công khai (expose) các phương thức để chương trình client có thể truy cập chúng qua mạng, bất kể client được viết bằng Java, shell script hay bất kỳ ngôn ngữ nào khác. Web service có tính chất phi trạng thái (stateless), tức là nó không duy trì session của người dùng giống như các ứng dụng web thông thường.
Một số ưu điểm của web service là:
Có hai loại web service chính:
SOAP là viết tắt của Simple Object Access Protocol, một chuẩn giao thức dựa trên XML. Nó được dùng để thiết kế và phát triển web service. Do sử dụng XML, SOAP không phụ thuộc vào nền tảng hay ngôn ngữ lập trình nào. Vì vậy, server có thể được xây dựng bằng Java trong khi client được viết bằng .NET, PHP,… và ngược lại.
SOAP web service thừa hưởng mọi ưu điểm của web service nói chung, cùng với một số lợi thế riêng sau đây:
Một số nhược điểm của giao thức SOAP bao gồm:
WSDL là viết tắt của Web Service Description Language (Ngôn ngữ mô tả dịch vụ web). Nó là file tài liệu XML cung cấp các thông tin kỹ thuật về web service. Một số thông tin hữu ích trong WSDL bao gồm: tên phương thức, các kiểu port, endpoint (điểm truy cập) của service, binding (ràng buộc), tham số của phương thức, v.v.
Một số thẻ chính trong một file WSDL XML bao gồm:
xsd:import namespace và schemaLocation: Cung cấp URL của WSDL và một namespace (không gian tên) riêng biệt cho web service.message: Dùng cho các tham số của phương thức.part: Dùng cho tên và kiểu của tham số.portType: Tên của service, một file WSDL có thể chứa nhiều service.operation: Chứa tên phương thức.soap:address: Dùng cho URL của endpoint.UDDI là viết tắt của Universal Description, Discovery and Integration. Đây là một thư mục chứa thông tin về các web service, cho phép các ứng dụng client tìm kiếm dịch vụ mình cần. Các web service có thể đăng ký với server UDDI để các ứng dụng client khác có thể tìm thấy và sử dụng nó.
Theo phương pháp Top down (từ trên xuống), đầu tiên tài liệu WSDL được tạo trước để thiết lập contract (giao kèo) giữa web service và client, sau đó ta mới viết code. Phương pháp này còn được gọi là contract-first.
Việc triển khai theo cách này phức tạp hơn vì các class phải được viết sao cho tuân thủ đúng contract đã định nghĩa trong WSDL. Lợi ích của phương pháp này là cả client và server có thể được phát triển cùng một lúc.
Ngược lại, với phương pháp Bottom up (từ dưới lên), code của web service được viết trước, sau đó WSDL mới được tạo ra. Phương pháp này còn được gọi là contract-last.
Cách tiếp cận này dễ triển khai hơn vì WSDL được tự động sinh ra dựa trên mã nguồn đã có. Tuy nhiên, nhược điểm là phía phát triển client phải chờ cho đến khi server cung cấp WSDL thì mới có thể bắt đầu công việc.
REST là từ viết tắt của REpresentational State Transfer. Đây là một mô hình để phát triển các ứng dụng có thể truy cập qua mạng. Phương thức này được Roy Fielding giới thiệu trong luận án tiến sĩ của ông vào năm 2000.
REST có một kiến trúc client-server phi trạng thái, trong đó các web service được xem như những resource (tài nguyên) có thể được định danh thông qua URI của chúng. Ứng dụng client có thể sử dụng các phương thức HTTP như GET/POST để gọi các web service dạng RESTful.
REST không quy định một giao thức cụ thể nào. Nhưng trong thực tế, nó gần như luôn được sử dụng trên nền HTTP/HTTPS. So với SOAP, các web service dạng này nhẹ hơn và không tuân theo một tiêu chuẩn cứng nhắc nào. Ta có thể sử dụng XML, JSON, text hoặc bất kỳ loại dữ liệu nào khác cho request và response.
Một số ưu điểm của REST web service là:
Một số nhược điểm của REST là:
Resource (tài nguyên) là khái niệm nền tảng của kiến trúc RESTful. Một resource là một đối tượng có kiểu, có mối quan hệ với các resource khác và có các phương thức để thao tác trên nó. Resource được định danh bằng URI, các phương thức HTTP mà chúng hỗ trợ, cùng với kiểu và định dạng dữ liệu của request/response.
GET, POST, PUT, DELETE và HEAD là các phương thức HTTP được hỗ trợ trong RESTful web service.
| SOAP | REST |
|---|---|
| SOAP là một giao thức chuẩn để tạo web service. | REST là một mô hình kiến trúc để tạo web service. |
| SOAP là viết tắt của Simple Object Access Protocol. | REST là viết tắt của REpresentational State Transfer. |
| SOAP sử dụng WSDL để công khai các phương thức được hỗ trợ và các chi tiết kỹ thuật. | REST công khai các phương thức thông qua URI, không có chi tiết kỹ thuật đi kèm. |
| Web service và chương trình client bị ràng buộc bởi contract WSDL. | REST không có contract nào được định nghĩa giữa server và client. |
| Web service và client có sự ràng buộc chặt chẽ bởi contract. | Web service REST có tính ràng buộc lỏng. |
| Việc học SOAP khó hơn, đòi hỏi phải tìm hiểu về cách tạo WSDL, tạo client stub, v.v. | Việc học REST đơn giản hơn, các class POJO có thể được tạo dễ dàng và hoạt động trên các phương thức HTTP đơn giản. |
| SOAP chỉ hỗ trợ định dạng dữ liệu XML. | REST hỗ trợ nhiều loại dữ liệu như XML, JSON, hình ảnh, v.v. |
| Web service SOAP khó bảo trì hơn. Bất kỳ thay đổi nào trong contract WSDL đều yêu cầu ta phải tạo lại client stub và sau đó sửa đổi code ở client. | Web service REST dễ bảo trì hơn so với SOAP. Một phương thức mới có thể được thêm vào mà không cần thay đổi ở phía client đối với các resource hiện có. |
| Web service SOAP có thể được kiểm thử bằng chương trình hoặc phần mềm như SoapUI. | REST có thể được kiểm thử dễ dàng thông qua lệnh cURL, trình duyệt và các extension như Postman trên Chrome. |
Web service SOAP có thể được kiểm thử tự động qua code bằng cách tạo client stub từ WSDL hoặc thông qua các phần mềm chuyên dụng như SoapUI. Trong khi đó, web service REST có thể dễ dàng được kiểm thử bằng lệnh curl và các extension trên trình duyệt. Các resource hỗ trợ phương thức GET thậm chí có thể được kiểm thử ngay trên trình duyệt mà không cần viết thêm chương trình nào.
Web service vốn có tính stateless (phi trạng thái), vì vậy chúng ta không thể duy trì session của người dùng.
Kiến trúc hướng dịch vụ (Service Oriented Architecture – SOA) là một mô hình kiến trúcmà ở đó các ứng dụng được thiết kế dưới dạng các service có thể được truy cập thông qua một giao thức truyền thông qua mạng. Còn SOA là một kiểu thiết kế và không đi sâu vào chi tiết triển khai. Web service có thể được xem như các service thuộc kiến trúc SOA và là một phương tiện để triển khai nó.
Đây là những header quan trọng trong RESTful web service. Header Accept cho web service biết client chấp nhận loại response nào. Ví dụ, nếu một web service có khả năng trả về response ở cả định dạng XML và JSON, và client gửi header Accept là "application/xml", thì response trả về sẽ là XML. Nếu header là "application/json", server sẽ gửi response dạng JSON.
Header Content-Type được sử dụng để báo cho server biết định dạng dữ liệu được gửi trong request. Nếu header Content-Type là "application/xml", server sẽ cố gắng phân tích dữ liệu đó dưới dạng XML. Header này rất hữu ích trong các request HTTP POST và PUT.
Web service hoạt động theo mô hình client-server, và việc lựa chọn giữa SOAP và REST hoàn toàn phụ thuộc vào yêu cầu của dự án. Hãy xem xét một số điều kiện ảnh hưởng đến lựa chọn của chúng ta:
JAX-WS là viết tắt của Java API for XML Web Services. Đây là một Java API dựa trên XML để xây dựng ứng dụng web service phía server và client. Nó là một phần của Java API chuẩn, vì vậy chúng ta không cần cài đặt bất kỳ thư viện nào khác khi làm việc với nó.
Chúng ta có thể tạo web service dạng SOAP bằng JAX-WS API. Một số framework khác cũng có thể được sử dụng là Apache Axis và Apache CXF. Lưu ý rằng chúng không phải là các bản triển khai của JAX-WS API, mà là các framework hoàn toàn độc lập. Chúng hoạt động trên mô hình Servlet để expose các lớp logic nghiệp vụ của bạn thành SOAP web service.
Một số annotation quan trọng được sử dụng trong JAX-WS API là:
@WebService@SOAPBinding@WebMethodjavax.xml.ws.Endpoint là gì?Lớp Endpoint cung cấp các phương thức hữu ích để tạo endpoint và publish (đưa triển khai hiện tại vào hoạt động như một web service). Điều này rất tiện lợi khi ta kiểm thử web service trước khi thực hiện các thay đổi sâu hơn để triển khai nó trên một server thực tế.
Kiểu RPC tạo ra tài liệu WSDL dựa trên tên phương thức và các tham số của nó mà không có định nghĩa kiểu nào trong tài liệu WSDL. Kiểu Document chứa thông tin về kiểu và có thể được xác thực nó dựa trên một schema đã định nghĩa trước.
Hãy xem xét sự khác biệt này qua một chương trình đơn giản ở dưới. Đây là một chương trình test đơn giản, trong đó ta sử dụng Endpoint để publish một web service SOAP đơn giản.
package com.journaldev.jaxws.service;import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.xml.ws.Endpoint;
@WebService @SOAPBinding(style = SOAPBinding.Style.RPC) public class TestService {
@WebMethod public String sayHello(String msg){ return "Hello "+msg; } public static void main(String[] args){ Endpoint.publish("<https://localhost:8888/testWS>", new TestService()); }}
Khi ta chạy chương trình trên và truy cập vào WSDL, nó sẽ trả về một file XML như sau:
<?xml version='1.0' encoding='UTF-8'?> <!-- Published by JAX-WS RI (<https://jax-ws.java.net>). RI's version is JAX-WS RI 2.2.10 svn-revision#919b322c92f13ad085a933e8dd6dd35d4947364b. --><!-- Generated by JAX-WS RI (<https://jax-ws.java.net>). RI's version is JAX-WS RI 2.2.10 svn-revision#919b322c92f13ad085a933e8dd6dd35d4947364b. --> <definitions xmlns:wsu="<https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd>" xmlns:wsp="<https://www.w3.org/ns/ws-policy>" xmlns:wsp1_2="<https://schemas.xmlsoap.org/ws/2004/09/policy>" xmlns:wsam="<https://www.w3.org/2007/05/addressing/metadata>" xmlns:soap="<https://schemas.xmlsoap.org/wsdl/soap/>" xmlns:tns="<https://service.jaxws.journaldev.com/>" xmlns:xsd="<https://www.w3.org/2001/XMLSchema>" xmlns="<https://schemas.xmlsoap.org/wsdl/>" targetNamespace="<https://service.jaxws.journaldev.com/>" name="TestServiceService"> <types/> <message name="sayHello"> <part name="arg0" type="xsd:string"/> </message> <message name="sayHelloResponse"> <part name="return" type="xsd:string"/> </message> <portType name="TestService"> <operation name="sayHello"> <input wsam:Action="<https://service.jaxws.journaldev.com/TestService/sayHelloRequest>" message="tns:sayHello"/> <output wsam:Action="<https://service.jaxws.journaldev.com/TestService/sayHelloResponse>" message="tns:sayHelloResponse"/> </operation> </portType> <binding name="TestServicePortBinding" type="tns:TestService"> <soap:binding transport="<https://schemas.xmlsoap.org/soap/http>" style="rpc"/> <operation name="sayHello"> <soap:operation soapAction=""/> <input> <soap:body use="literal" namespace="<https://service.jaxws.journaldev.com/>"/> </input> <output> <soap:body use="literal" namespace="<https://service.jaxws.journaldev.com/>"/> </output> </operation> </binding> <service name="TestServiceService"> <port name="TestServicePort" binding="tns:TestServicePortBinding"> <soap:address location="<https://localhost:8888/testWS>"/> </port> </service> </definitions>
Trong trường hợp này, phần tử types bị trống và không thể được xác thực với bất kỳ schema nào. Bây giờ, chỉ cần thay đổi SOAPBinding.Style.RPC thành SOAPBinding.Style.DOCUMENT, ta sẽ nhận được một WSDL khác.
<?xml version='1.0' encoding='UTF-8'?> <!-- Published by JAX-WS RI (<https://jax-ws.java.net>). RI's version is JAX-WS RI 2.2.10 svn-revision#919b322c92f13ad085a933e8dd6dd35d4947364b. --><!-- Generated by JAX-WS RI (<https://jax-ws.java.net>). RI's version is JAX-WS RI 2.2.10 svn-revision#919b322c92f13ad085a933e8dd6dd35d4947364b. --> <definitions xmlns:wsu="<https://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd>" xmlns:wsp="<https://www.w3.org/ns/ws-policy>" xmlns:wsp1_2="<https://schemas.xmlsoap.org/ws/2004/09/policy>" xmlns:wsam="<https://www.w3.org/2007/05/addressing/metadata>" xmlns:soap="<https://schemas.xmlsoap.org/wsdl/soap/>" xmlns:tns="<https://service.jaxws.journaldev.com/>" xmlns:xsd="<https://www.w3.org/2001/XMLSchema>" xmlns="<https://schemas.xmlsoap.org/wsdl/>" targetNamespace="<https://service.jaxws.journaldev.com/>" name="TestServiceService"> <types> <xsd:schema> <xsd:import namespace="<https://service.jaxws.journaldev.com/>" schemaLocation="<https://localhost:8888/testWS?xsd=1>"/> </xsd:schema> </types> <message name="sayHello"> <part name="parameters" element="tns:sayHello"/> </message> <message name="sayHelloResponse"> <part name="parameters" element="tns:sayHelloResponse"/> </message> <portType name="TestService"> <operation name="sayHello"> <input wsam:Action="<https://service.jaxws.journaldev.com/TestService/sayHelloRequest>" message="tns:sayHello"/> <output wsam:Action="<https://service.jaxws.journaldev.com/TestService/sayHelloResponse>" message="tns:sayHelloResponse"/> </operation> </portType> <binding name="TestServicePortBinding" type="tns:TestService"> <soap:binding transport="<https://schemas.xmlsoap.org/soap/http>" style="document"/> <operation name="sayHello"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="TestServiceService"> <port name="TestServicePort" binding="tns:TestServicePortBinding"> <soap:address location="<https://localhost:8888/testWS>"/> </port> </service> </definitions>
Khi mở schemaLocation URL trong trình duyệt, ta sẽ nhận được file XML sau:
<?xml version='1.0' encoding='UTF-8'?> <!-- Published by JAX-WS RI (<https://jax-ws.java.net>). RI's version is JAX-WS RI 2.2.10 svn-revision#919b322c92f13ad085a933e8dd6dd35d4947364b. --> <xs:schema xmlns:tns="<https://service.jaxws.journaldev.com/>" xmlns:xs="<https://www.w3.org/2001/XMLSchema>" version="1.0" targetNamespace="<https://service.jaxws.journaldev.com/>"><xs:element name="sayHello" type="tns:sayHello"/>
<xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/>
<xs:complexType name="sayHello"> <xs:sequence> <xs:element name="arg0" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType>
<xs:complexType name="sayHelloResponse"> <xs:sequence> <xs:element name="return" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:schema>
Ta có thể truy cập file tài liệu WSDL bằng cách thêm ?wsdl vào cuối URL của endpoint SOAP. Trong ví dụ trên, chúng ta có thể truy cập nó tại địa chỉ https://localhost:8888/testWS?wsdl.
File này được sử dụng để cung cấp chi tiết về các endpoint khi một web service JAX-WS được triển khai trong một servlet container như Tomcat. File này nằm trong thư mục WEB-INF và chứa tên endpoint, lớp triển khai và URL pattern.
Ví dụ.
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="<https://java.sun.com/xml/ns/jax-ws/ri/runtime>" version="2.0">
<endpoint
name="PersonServiceImpl"
implementation="com.journaldev.jaxws.service.PersonServiceImpl"
url-pattern="/personWS"/>
</endpoints>
Java API for RESTful Web Services (JAX-RS) là một Java API để tạo các web service dạng REST. JAX-RS sử dụng các annotation để đơn giản hóa việc phát triển và triển khai này. Nó là một phần của JDK, vì vậy bạn không cần phải thêm bất kỳ thư viện nào để sử dụng các annotation của nó.
Có hai phiên bản triển khai chính của JAX-RS API:
web.xml và thêm các dependency cần thiết. Lưu ý rằng JAX-RS API là một phần của JDK chứ không phải Jersey, vì vậy chúng ta phải thêm các file phụ thuộc jar của Jersey vào ứng dụng của mình.Chúng ta có thể sử dụng công cụ wsimport để tạo ra các client stub (bên trung gian đại diện cho client). Công cụ này đi kèm với bản cài đặt chuẩn của JDK. Dưới đây là một ví dụ dùng wsimport cho một dự án JAX-WS.
Một số annotation quan trọng của JAX-RS là:
@Path: dùng để chỉ định đường dẫn tương đối của class và phương thức. Chúng ta có thể lấy URI của một web service bằng cách quét giá trị của annotation Path.@GET, @PUT, @POST, @DELETE và @HEAD: dùng để chỉ định loại HTTP request cho một phương thức.@Produces, @Consumes: dùng để chỉ định các loại request và response.@PathParam: dùng để liên kết tham số của phương thức với một giá trị trong đường dẫn bằng cách phân tích nó.Annotation XmlRootElement được JAXB sử dụng để chuyển đổi đối tượng Java sang XML và ngược lại. Vì vậy, chúng ta phải chú thích (annotate) các lớp model bằng annotation này.
Để đặt mã trạng thái HTTP (status code) khác 200, chúng ta phải sử dụng lớp javax.ws.rs.core.Response cho response. Dưới đây là ví dụ dùng nó để trả về các status code khác nhau.
Vậy là chúng ta đã cùng nhau khám phá một loạt các câu hỏi phỏng vấn về web service. Danh sách này là một điểm khởi đầu tốt để bạn hệ thống lại kiến thức và sẵn sàng cho những thử thách phía trước. Nếu bạn cảm thấy có bất kỳ câu hỏi nào quan trọng đã bị bỏ sót, hoặc bạn có cách tiếp cận khác cho một vấn đề nào đó, đừng ngần ngại chia sẻ suy nghĩ của mình trong phần bình luận bên dưới nhé.