杰瑞科技汇

Java webservice服务如何快速搭建与调用?

  1. 什么是 WebService? (概念与核心思想)
  2. Java WebService 的演进史 (从 SOAP 到 REST)
  3. 主流的 Java WebService 技术栈
    • JAX-WS (Java API for XML Web Services) - 用于 SOAP 服务
    • JAX-RS (Java API for RESTful Web Services) - 用于 REST 服务
  4. 实战示例
    • JAX-WS (使用 JDK 内置的 wsimportEndpoint)
    • JAX-RS (使用流行的 Jersey 框架)
  5. 如何选择? (SOAP vs REST)
  6. 现代趋势与替代方案

什么是 WebService?

WebService 是一种跨编程语言、跨操作系统的远程调用技术,它的核心思想是:

Java webservice服务如何快速搭建与调用?-图1
(图片来源网络,侵删)

让不同平台、不同语言开发的应用程序,能够通过网络进行交互和数据交换。

WebService 的主要特点:

  • 跨平台性:只要能通过网络发送和接收 XML 或 JSON 格式的数据,任何平台都可以调用 WebService。
  • 基于标准:通常基于一些广泛接受的标准,如 HTTP、XML、SOAP、WSDL、UDDI(早期)等。
  • 松耦合:服务提供方和服务调用方之间不需要知道对方的内部实现细节,只需约定好接口(通过 WSDL 或 API 文档)即可。

Java WebService 的演进史

Java WebService 技术主要经历了两个主要阶段:

SOAP 时代 (The Old Way)

  • 协议:SOAP (Simple Object Access Protocol),它是一个基于 XML 的协议,非常“重量级”和“严谨”。
  • 核心:服务端和客户端之间通过 XML 格式的 SOAP 消息进行通信。
  • 优点
    • 标准化:有严格的规范(WSDL - Web Services Description Language),可以自动生成客户端和服务端代码。
    • 安全性:内置了安全、事务等扩展标准。
    • 协议无关:虽然通常用 HTTP,但也可以通过 SMTP、TCP 等协议传输。
  • 缺点
    • 性能差:XML 格式冗长,解析开销大。
    • 开发复杂:配置繁琐,学习曲线陡峭。
    • 可读性差:生成的 SOAP 消息在浏览器中难以直接阅读和调试。
  • 代表技术JAX-WS

REST 时代 (The Modern Way)

  • 协议:REST (Representational State Transfer),它不是一种标准,而是一种软件架构风格
  • 核心:将一切数据视为“资源”,通过标准的 HTTP 方法(GET, POST, PUT, DELETE)来操作这些资源。
  • 优点
    • 轻量级:通常使用 JSON 或 HTML 作为数据格式,数据量小,解析快。
    • 开发简单:完全利用 HTTP 协议的特性,易于理解和实现。
    • 易于缓存:可以直接利用 HTTP 缓存机制。
    • 前后端分离:非常适合现代 Web 开发,前端通过 AJAX 调用后端 REST API。
  • 缺点
    • 无状态:服务端不保存客户端状态,所有状态需要由客户端自己维护。
    • 安全性:没有像 SOAP 那样内置的安全标准,需要自己实现或依赖 OAuth2、JWT 等框架。
  • 代表技术JAX-RS

在企业级应用内部,SOAP 仍有其一席之地(尤其是在需要严格契约和安全性的场景),但在互联网应用和前后端分离的架构中,REST 已成为绝对的主流

Java webservice服务如何快速搭建与调用?-图2
(图片来源网络,侵删)

主流的 Java WebService 技术栈

JAX-WS (SOAP)

JAX-WS 是 Java 官方定义的一套用于创建 SOAP Web 服务的 API,它极大地简化了 SOAP 服务的开发。

核心概念

  • SEI (Service Endpoint Interface):服务端接口,定义了服务提供的方法。
  • SIB (Service Implementation Bean):服务端实现类,实现了 SEI 接口。
  • WSDL (Web Services Description Language):XML 文件,描述了服务的地址、可用的方法、参数和返回值格式,客户端通过 WSDL 文件生成调用代码。

常用工具

  • wsimport:JDK 自带的命令行工具,根据 WSDL 文件生成客户端的 Java 代码(SEI 和 SIB 的客户端存根)。
  • Endpoint:JDK 自带的类,用于在内存中发布一个简单的 SOAP 服务,无需 Web 容器(如 Tomcat)。

JAX-RS (REST)

JAX-RS 是 Java 官方定义的一套用于创建 RESTful Web 服务的 API,它只定义了一套规范,具体实现由第三方厂商提供。

Java webservice服务如何快速搭建与调用?-图3
(图片来源网络,侵删)

核心概念

  • @Path:标注在类或方法上,定义资源的 URI 路径。
  • @GET, @POST, @PUT, @DELETE:标注在方法上,定义对应的 HTTP 方法。
  • @Produces:标注在方法上,定义该方法返回的媒体类型,如 application/json, text/xml
  • @Consumes:标注在方法上,定义该方法可以接受的请求体媒体类型。
  • @PathParam, @QueryParam, @FormParam:用于从 URL 路径、查询参数或表单数据中获取值。

主流实现框架

  1. Jersey:参考实现,由 Oracle 赞助,功能强大,社区活跃。(推荐初学者使用)
  2. RESTEasy:JBoss(Red Hat)出品,与 JBoss/WildFly 应用服务器集成得非常好。
  3. Apache CXF:功能全面,除了支持 JAX-RS,还支持 JAX-WS 和许多其他协议。

实战示例

示例 1:JAX-WS (SOAP)

目标:创建一个简单的 SOAP 服务,根据用户名返回问候语。

服务端实现

// SEI (服务端接口)
import javax.jws.WebService;
import javax.jws.WebMethod;
@WebService
public interface GreetingService {
    @WebMethod
    String sayHello(String name);
}
// SIB (服务端实现)
import javax.jws.WebService;
@WebService(endpointInterface = "com.example.GreetingService")
public class GreetingServiceImpl implements GreetingService {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
}
// 发布服务 (可以使用 Main 方法发布)
import javax.xml.ws.Endpoint;
public class GServicePublisher {
    public static void main(String[] args) {
        String address = "http://localhost:8888/ws/greeting";
        Endpoint.publish(address, new GreetingServiceImpl());
        System.out.println("SOAP Service is published at: " + address);
    }
}

运行 GServicePublisher,服务就启动了,访问 http://localhost:8888/ws/greeting?wsdl,可以看到 WSDL 文件。

客户端调用

方法A:使用 wsimport 生成客户端代码

  1. 打开命令行,执行:

    wsimport -p com.example.client -keep http://localhost:8888/ws/greeting?wsdl

    这会在 com.example.client 包下生成一堆 Java 文件。

  2. 编写客户端代码:

    import com.example.client.GreetingService;
    import com.example.client.GreetingService_Service;
    public class GServiceClient {
        public static void main(String[] args) {
            // 创建服务视图
            GreetingService_Service service = new GreetingService_Service();
            // 获取服务端点
            GreetingService port = service.getGreetingServicePort();
            // 调用方法
            String response = port.sayHello("WebService User");
            System.out.println(response); // 输出: Hello, WebService User!
        }
    }

示例 2:JAX-RS (REST with Jersey)

目标:创建一个 REST 服务,提供用户信息。

环境准备

  • 创建一个 Maven 项目。
  • pom.xml 中添加 Jersey 依赖:
<dependencies>
    <!-- Jersey 核心依赖 -->
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.39</version>
    </dependency>
    <!-- JSON 支持 -->
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-binding</artifactId>
        <version>2.39</version>
    </dependency>
</dependencies>

服务端实现

// 资源类
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.HashMap;
import java.util.Map;
@Path("/users") // 定义基础路径
public class UserResource {
    // 模拟一个数据库
    private static final Map<Integer, String> userDB = new HashMap<>();
    static {
        userDB.put(1, "Alice");
        userDB.put(2, "Bob");
    }
    @GET
    @Path("/{userId}") // 定义路径参数
    @Produces(MediaType.APPLICATION_JSON) // 指定返回 JSON 格式
    public String getUser(@PathParam("userId") int userId) {
        String userName = userDB.get(userId);
        if (userName == null) {
            // 返回 404 Not Found
            throw new javax.ws.rs.NotFoundException("User with id " + userId + " not found.");
        }
        // 返回简单的 JSON 字符串
        return String.format("{\"id\": %d, \"name\": \"%s\"}", userId, userName);
    }
}

配置 Web 容器 (web.xml)

src/main/webapp/WEB-INF/web.xml 中配置 Jersey Servlet:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.example</param-value> <!-- 指定你的资源类所在的包 -->
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>
</web-app>

部署和测试

  • 将项目打包成 WAR 文件,部署到 Tomcat 或其他 Servlet 容器中。
  • 启动服务器,访问:
    • http://localhost:8080/your-app-name/api/users/1 (应返回 {"id": 1, "name": "Alice"})
    • http://localhost:8080/your-app-name/api/users/2 (应返回 {"id": 2, "name": "Bob"})
    • http://localhost:8080/your-app-name/api/users/3 (应返回 404 Not Found)

你可以使用 Postman 或浏览器插件(如 REST Client)来更方便地测试。


如何选择?(SOAP vs REST)

特性 SOAP REST
协议 严格的协议(基于 XML) 架构风格(基于 HTTP)
数据格式 主要是 XML 主要是 JSON, XML, HTML
消息格式 标准化的 SOAP Envelope 灵活的,通常是纯文本 JSON
性能 较慢,XML 解析开销大 较快,JSON 轻量级
标准化 高度标准化(WSDL, WS-Security) 无统一标准,依赖 API 文档
安全性 内置安全标准和事务支持 需要自行实现或集成 OAuth2, JWT 等
缓存 不支持 利用 HTTP 缓存机制
学习曲线 陡峭 平缓
适用场景 企业应用集成(B2B)、金融、电信等需要高安全性和严格契约的场景。 互联网应用、移动后端、微服务、前后端分离项目。

简单来说

  • 如果你的服务需要被不同语言、不同平台的遗留系统调用,并且对安全性和事务有极高要求,可以考虑 SOAP
  • 如果你在开发新的、现代化的 Web 或移动应用,追求开发效率、性能和灵活性REST 是不二之选。

现代趋势与替代方案

随着技术的发展,传统的 WebService 概念也在演变:

  1. Spring Boot + Spring WebFlux:在 Java 世界,Spring Boot 已经成为事实标准,它内置了对 REST 的完美支持(使用 @RestController),并以其简洁的配置、强大的生态系统(如 Spring Security, Spring Data)极大地简化了 Web 服务的开发,对于新的项目,Spring Boot 是首选
  2. gRPC:由 Google 推出,使用 HTTP/2 和 Protocol Buffers (Protobuf) 作为数据格式,它性能极高、支持双向流、强类型定义,非常适合微服务架构内部的服务间通信。
  3. GraphQL:由 Facebook 推出,是一种 API 查询语言,它允许客户端精确地请求所需的数据,避免了 REST 中常见的“过度获取”或“获取不足”的问题,适用于需要高度灵活性的前端应用
  • 对于 SOAP,JAX-WS 依然是标准,但使用场景越来越少。
  • 对于 RESTJAX-RS (Jersey/RESTEasy) 是一个很好的选择,但 Spring Boot 凭借其易用性和生态优势,在当前市场中占据了主导地位。
  • 在特定高性能或微服务场景下,可以关注 gRPCGraphQL

希望这份详细的指南能帮助你全面了解 Java WebService!

分享:
扫描分享到社交APP
上一篇
下一篇