杰瑞科技汇

Java webservice如何实现?

核心概念

在开始之前,我们先理解几个关键概念:

Java webservice如何实现?-图1
(图片来源网络,侵删)
  1. WebService: 一种跨编程语言、跨操作系统平台的远程调用技术,它使用 XML 进行数据交换,并通过 SOAP (Simple Object Access Protocol) 协议在网络上传输。
  2. SOAP (Simple Object Access Protocol): 用于交换结构化信息的协议,它基于 XML,独立于平台和语言。
  3. WSDL (Web Services Description Language): 一个 XML 文件,用于描述 WebService 的功能、接口、参数、返回值以及如何访问它,你可以把它理解成 WebService 的“说明书”。
  4. Endpoint (端点): WebService 的访问地址,通常是一个 URL。

JAX-WS (Java API for XML Web Services) - 现代、主流

这是目前 Java 官方推荐的标准,用于构建和消费 SOAP WebService,它极大地简化了开发过程,你只需要关注业务逻辑,而不用关心底层的 XML 和 SOAP 消息。

JAX-WS 是 Java EE 的一部分,现在也包含在 Jakarta EE 中,主流的实现有 Metro (GlassFish)Apache CXF

这里我们使用 JDK 自带的 wsimport 工具Metro 来演示,因为它最简单,无需额外引入复杂的框架。

服务端实现

目标: 创建一个提供查询用户信息的 WebService。

Java webservice如何实现?-图2
(图片来源网络,侵删)

步骤:

第一步:创建一个标准的 Java 项目

使用你喜欢的 IDE (如 IntelliJ IDEA, Eclipse) 创建一个 Maven 或 Gradle 项目。

第二步:定义服务接口和实现类

Java webservice如何实现?-图3
(图片来源网络,侵删)

你需要一个接口(或一个类)来定义 WebService 的方法。

UserService.java (接口)

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// @WebService 注解将这个类标记为一个 WebService
@WebService
// @SOAPBinding 指定 SOAP 协议的样式,默认是 DOCUMENT
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public interface UserService {
    // @WebMethod 将此方法暴露为 WebService 的一个操作
    // @WebParam 指定参数的名称
    @WebMethod
    String getUserInfo(@WebParam(name = "userId") String userId);
}

UserServiceImpl.java (实现类)

import javax.jws.WebService;
// 注意:实现类需要使用 @WebService 注解,并指定 endpointInterface 属性
// 这表示这个类实现了上面定义的接口
@WebService(endpointInterface = "com.example.webservice.UserService")
public class UserServiceImpl implements UserService {
    @Override
    public String getUserInfo(String userId) {
        // 模拟业务逻辑
        if ("001".equals(userId)) {
            return "User ID: 001, Name: Alice, Email: alice@example.com";
        } else if ("002".equals(userId)) {
            return "User ID: 002, Name: Bob, Email: bob@example.com";
        } else {
            return "User not found with ID: " + userId;
        }
    }
}

第三步:发布 WebService

你需要一个主类来启动一个内嵌的 HTTP 服务器,并将你的服务发布上去。

Publisher.java

import javax.xml.ws.Endpoint;
public class Publisher {
    public static void main(String[] args) {
        // 创建服务实现类的实例
        UserServiceImpl userServiceImpl = new UserServiceImpl();
        // 定义服务的访问地址 (Endpoint URL)
        String address = "http://localhost:8888/ws/user";
        // 发布服务
        Endpoint.publish(address, userServiceImpl);
        System.out.println("WebService is published at: " + address);
        System.out.println("You can access the WSDL at: " + address + "?wsdl");
    }
}

第四步:运行和测试

  1. 运行 Publisher.javamain 方法。
  2. 打开浏览器,访问 http://localhost:8888/ws/user?wsdl
  3. 如果看到一个 XML 文件(即 WSDL 文件),说明你的 WebService 发布成功了!

客户端实现

目标: 创建一个客户端程序来调用上面发布的 WebService。

步骤:

第一步:使用 wsimport 生成客户端代码

wsimport 是 JDK 自带的工具,可以根据 WSDL 文件生成客户端所需的 Java 代码(存根和框架)。

打开你的终端(或命令提示符),进入到客户端项目的 src/main/java 目录下,执行以下命令:

wsimport -keep -p com.example.webservice.client http://localhost:8888/ws/user?wsdl
  • -keep: 生成源代码。
  • -p com.example.webservice.client: 指定生成代码的包名。
  • http://...?wsdl: WSDL 文件的 URL。

执行后,会在你指定的包下生成一堆 .java 文件(如 UserService.java, UserService_Service.java, UserInfo.java 等)。

第二步:编写客户端调用代码

你可以像调用本地方法一样调用远程的 WebService 了。

WebServiceClient.java

import com.example.webservice.client.UserService;
import com.example.webservice.client.UserService_Service;
public class WebServiceClient {
    public static void main(String[] args) {
        // 通过 Service 类创建一个服务的代理
        UserService_Service service = new UserService_Service();
        // 从 Service 中获取 Port(端口),即服务的实现
        UserService userService = service.getUserServicePort();
        // 调用远程方法
        String response1 = userService.getUserInfo("001");
        System.out.println("Response for '001': " + response1);
        String response2 = userService.getUserInfo("002");
        System.out.println("Response for '002': " + response2);
        String response3 = userService.getUserInfo("003");
        System.out.println("Response for '003': " + response3);
    }
}

第三步:运行客户端

运行 WebServiceClient.java,你将看到从服务端返回的结果。


Spring Boot + JAX-WS (更现代的整合方式)

在 Spring Boot 项目中集成 JAX-WS,可以更好地利用 Spring 的生态系统(如依赖注入、事务管理等)。

服务端实现 (Spring Boot):

  1. 添加依赖pom.xml 中添加 cxf-spring-boot-starter-jaxws

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
        <version>3.4.5</version> <!-- 请使用最新版本 -->
    </dependency>
  2. 配置 Endpoint 创建一个配置类来发布你的服务。

    import com.example.webservice.UserService;
    import com.example.webservice.UserServiceImpl;
    import org.apache.cxf.jaxws.EndpointImpl;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import javax.xml.ws.Endpoint;
    @Configuration
    public class CxfConfig {
        @Bean
        public UserService userService() {
            return new UserServiceImpl();
        }
        @Bean
        public Endpoint endpoint() {
            EndpointImpl endpoint = new EndpointImpl(springApplicationContext(), userService());
            endpoint.publish("/user"); // 发布路径
            return endpoint;
        }
        // 获取 Spring 应用上下文,CXF 需要它来注入依赖
        @Bean
        public org.springframework.context.ApplicationContext springApplicationContext() {
            return new org.springframework.context.annotation.AnnotationConfigApplicationContext();
        }
    }
  3. 访问地址 启动 Spring Boot 应用后,服务会自动发布在 http://<your-host>:<port>/user?wsdl


JAX-RS (Java API for RESTful Web Services) - 现代、轻量级

虽然你问的是 WebService,但很多时候大家说的其实是 RESTful WebService,它更轻量、更简单,基于 HTTP 协议,使用 JSON 数据格式,是目前 Web API 的主流。

服务端实现 (Spring Boot + JAX-RS - 例如使用 RESTEasy)

  1. 添加依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 如果你需要 JAX-RS 的特定实现,RESTEasy -->
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-spring-boot-starter</artifactId>
        <version>3.15.1.Final</version>
    </dependency>
  2. 创建资源类

    import org.springframework.web.bind.annotation.*;
    // @RestController = @Controller + @ResponseBody
    @RestController
    @RequestMapping("/api/users") // 对应 REST 的路径
    public class UserResource {
        // @GetMapping 对应 HTTP GET 请求
        @GetMapping("/{userId}")
        public String getUserInfo(@PathVariable String userId) {
            if ("001".equals(userId)) {
                return "User ID: 001, Name: Alice, Email: alice@example.com (from REST)";
            }
            return "User not found with ID: " + userId;
        }
    }
  3. 测试 启动应用,访问 http://localhost:8080/api/users/001,浏览器会直接返回 JSON 格式的字符串。

客户端实现 (Spring Boot + RestTemplate 或 WebClient)

使用 RestTemplate (传统) 或 WebClient (响应式,推荐) 来调用 REST API。

import org.springframework.web.client.RestTemplate;
public class RestApiClient {
    public static void main(String[] args) {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://localhost:8080/api/users/001";
        // 直接发送 GET 请求,并接收响应体 (String)
        String response = restTemplate.getForObject(url, String.class);
        System.out.println("REST API Response: " + response);
    }
}

Apache Axis2 (经典、功能强大)

这是一个非常老牌且功能强大的框架,支持 SOAP 1.1, 1.2 和 RESTful 风格,它的架构比 JAX-WS 更灵活,但配置也更复杂。对于新项目,一般不推荐,除非需要处理非常复杂的遗留系统或特定需求。

服务端实现 (Axis2) 大致步骤:

  1. 下载并解压 Axis2
  2. 创建服务存档:将你的服务类和依赖打包成一个 .aar (Axis2 Archive) 文件。
  3. 部署服务:将 .aar 文件放到 Axis2 的 repository/services 目录下。
  4. 启动 Axis2 服务器
  5. 访问 http://localhost:8080/axis2/services/listServices 查看已部署的服务。

总结与对比

特性 JAX-WS (标准) Spring Boot + JAX-WS JAX-RS (RESTful) Apache Axis2
协议 SOAP SOAP HTTP (JSON) SOAP, REST
数据格式 XML XML JSON, XML, Text XML, JSON 等
复杂度 中等 中等 (依赖 Spring)
性能 较低 (XML 解析开销) 较低 较低
适用场景 企业级应用、与遗留系统集成、需要强类型契约 基于 Spring 生态的 SOAP 服务 现代 Web API、移动端后端、微服务 遗留系统维护、复杂 SOAP 处理
推荐度 推荐 (如果必须用 SOAP) 推荐 (如果项目已经是 Spring) 强烈推荐 (对于新项目) 不推荐 (除非特殊需求)
  • 如果你的项目 必须使用 SOAP 协议,请选择 JAX-WS,如果是 Spring 项目,优先考虑 Spring Boot + JAX-WS
  • 如果你正在构建一个新的 Web API,并且没有历史包袱,请选择 JAX-RS (RESTful),这是当前业界的事实标准。
  • Apache Axis2 可以作为一个备选,用于处理复杂的 SOAP 场景或维护旧系统,但对于新项目来说过于笨重。
分享:
扫描分享到社交APP
上一篇
下一篇