杰瑞科技汇

Java webservice远程调用如何实现高效通信?

WebService 的核心思想是跨平台、跨语言的远程通信,它使用标准的 XML 格式进行数据交换,并通过 HTTP 协议进行传输,在 Java 生态中,主要有三种技术来实现 WebService 调用:

Java webservice远程调用如何实现高效通信?-图1
(图片来源网络,侵删)
  1. JAX-WS (Java API for XML Web Services):这是 Java 官方标准,是当前最主流、最成熟的技术,它简化了 SOAP (Simple Object Access Protocol) WebService 的创建和调用。
  2. JAX-RS (Java API for RESTful Web Services):这是用于创建 RESTful Web 服务的 Java API,虽然严格来说它不叫 "WebService"(传统上指 SOAP),但现在它已成为 Web 服务领域的事实标准,因其轻量、简单而被广泛使用。
  3. Apache CXF / Axis2:这些都是强大的第三方框架,它们不仅支持 JAX-WS 和 JAX-RS 标准,还提供了更多高级功能和企业级支持。

下面我们分别对这几种方式进行详细说明,并提供代码示例。


JAX-WS (SOAP WebService)

JAX-WS 是 Java EE 的一部分,无需额外引入复杂框架,非常适合标准的、强类型的、需要高安全性的企业级应用。

服务端 创建

你需要一个服务端来提供 WebService。

步骤:

Java webservice远程调用如何实现高效通信?-图2
(图片来源网络,侵删)
  1. 定义一个服务接口(SEI - Service Endpoint Interface)。
  2. 使用 @WebService 注解标记该接口。
  3. 创建一个服务实现类(SIB - Service Implementation Bean)。
  4. 使用 @WebService@WebEndpoint 等注解实现接口。
  5. 通过 Endpoint 类发布服务。

代码示例:

接口 HelloService.java

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// @WebService 定义这是一个 WebService 接口
// targetNamespace 指定了命名空间,通常使用倒包名
@WebService(name = "HelloService", targetNamespace = "http://service.example.com/")
// SOAPBinding.Style.RPC 表示使用 RPC 风格
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface HelloService {
    // @WebMethod 指定这是一个对外暴露的 Web 方法
    @WebMethod
    String sayHello(String name);
}

实现类 HelloServiceImpl.java

import javax.jws.WebService;
// @WebService(endpointInterface = "com.example.service.HelloService") 
// 指定该实现类实现了哪个接口
@WebService(endpointInterface = "com.example.service.HelloService")
public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello(String name) {
        System.out.println("Server received request for: " + name);
        return "Hello, " + name + "!";
    }
}

发布服务 Publisher.java

Java webservice远程调用如何实现高效通信?-图3
(图片来源网络,侵删)
import javax.xml.ws.Endpoint;
public class Publisher {
    public static void main(String[] args) {
        // 定义服务的访问地址
        String address = "http://localhost:8080/hello";
        // 创建服务实现类的实例
        HelloService helloService = new HelloServiceImpl();
        // 发布服务
        Endpoint.publish(address, helloService);
        System.out.println("WebService has been published successfully!");
        System.out.println("You can access it at: " + address + "?wsdl");
    }
}

运行 Publisher,你的 SOAP WebService 就在 http://localhost:8080/hello 启动了,在浏览器中访问这个地址加上 ?wsdl 参数(如 http://localhost:8080/hello?wsdl),可以看到服务的 WSDL (Web Services Description Language) 文件,它描述了服务的所有接口。

客户端 调用

客户端有两种主要方式调用:动态代理静态客户端

动态代理(推荐)

这是最简单的方式,你只需要知道服务的 WSDL 地址即可。

代码示例:

import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;
public class JaxWsClient {
    public static void main(String[] args) throws Exception {
        // 1. 指定 WSDL 文件的地址
        URL wsdlUrl = new URL("http://localhost:8080/hello?wsdl");
        // 2. 定义服务的命名空间和服务名
        // 这些值可以从 WSDL 文件中找到
        QName qname = new QName("http://service.example.com/", "HelloServiceService");
        // 3. 创建 Service 实例
        Service service = Service.create(wsdlUrl, qname);
        // 4. 获取服务端点接口的代理对象
        HelloService helloService = service.getPort(HelloService.class);
        // 5. 像调用本地方法一样调用远程方法
        String result = helloService.sayHello("World");
        System.out.println("Client received result: " + result);
    }
}

静态客户端(通过 wsimport 工具生成)

这种方式需要先使用 JDK 自带的 wsimport 工具根据 WSDL 文件生成客户端代码。

  1. 生成客户端代码: 打开命令行,执行以下命令:

    wsimport -keep -p com.example.client http://localhost:8080/hello?wsdl
    • -keep:生成源代码。
    • -p:指定生成代码的包名。
    • 后面是 WSDL 的 URL。

    执行后,会在 com.example.client 包下生成一堆 Java 文件(接口、实现类等)。

  2. 使用生成的代码调用

    import com.example.client.HelloService;
    import com.example.client.HelloServiceService;
    public class StaticJaxWsClient {
        public static void main(String[] args) {
            // 创建服务实例
            HelloServiceService service = new HelloServiceService();
            // 获取服务端口
            HelloService helloPort = service.getHelloServicePort();
            // 调用方法
            String result = helloPort.sayHello("Static Client");
            System.out.println("Client received result: " + result);
        }
    }

JAX-RS (RESTful WebService)

REST (Representational State Transfer) 是一种更现代、更轻量级的架构风格,它通常使用 JSON 作为数据交换格式,通过 HTTP 动词(GET, POST, PUT, DELETE)来操作资源。

在 Java 中,实现 RESTful 服务最流行的框架是 JerseyRESTEasy,这里以 Jersey 为例。

服务端 创建

步骤:

  1. 添加 Jersey 依赖。
  2. 创建一个资源类(Resource Class),并用 @Path@GET@POST 等注解来定义资源和 HTTP 方法。
  3. 配置并启动一个内嵌的 HTTP 服务器(如 Grizzly)来部署资源。

Maven 依赖 (pom.xml)

<dependencies>
    <!-- Jersey 核心依赖 -->
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-grizzly2-http</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>

资源类 UserResource.java

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.*;
@Path("users") // 定义资源路径
public class UserResource {
    // 模拟一个数据库
    private Map<Long, User> userDB = new HashMap<>();
    private long idCounter = 1;
    // GET 请求,获取所有用户
    @GET
    @Produces(MediaType.APPLICATION_JSON) // 指定返回 JSON 格式
    public List<User> getAllUsers() {
        return new ArrayList<>(userDB.values());
    }
    // GET 请求,根据 ID 获取单个用户
    @GET
    @Path("{id}") // 路径参数
    @Produces(MediaType.APPLICATION_JSON)
    public Response getUserById(@PathParam("id") long id) {
        User user = userDB.get(id);
        if (user == null) {
            // 返回 404 Not Found
            return Response.status(Response.Status.NOT_FOUND).entity("User not found").build();
        }
        // 返回 200 OK 和用户对象
        return Response.ok(user).build();
    }
    // POST 请求,创建新用户
    @POST
    @Consumes(MediaType.APPLICATION_JSON) // 指定接收 JSON 格式
    @Produces(MediaType.APPLICATION_JSON)
    public Response createUser(User user) {
        user.setId(idCounter++);
        userDB.put(user.getId(), user);
分享:
扫描分享到社交APP
上一篇
下一篇