杰瑞科技汇

Java如何实现WebService?

  1. JAX-WS (Java API for XML Web Services):这是 Java 官方、标准的 WebService 实现方式,基于 SOAP 协议,它非常成熟,稳定,并且被广泛用于企业级应用中,Java 6 及以上版本已经内置了 JAX-WS 的实现(参考实现是 Metro)。
  2. JAX-RS (Java API for RESTful Web Services):这是用于实现 RESTful 风格 Web 服务的 API,它更轻量级,通常基于 HTTP 协议,使用 JSON 或 XML 作为数据格式,非常适合移动应用和前后端分离的架构,其最流行的实现是 JerseyRESTEasy

下面我将分别详细介绍这两种方式的实现步骤。

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

使用 JAX-WS (SOAP)

JAX-WS 的核心思想是,你只需要编写一个普通的 Java 接口和它的实现类,然后通过工具生成 WSDL (Web Services Description Language) 文件,客户端通过这个 WSDL 文件来了解如何调用你的服务。

创建服务端

步骤 1:创建服务接口

这是一个普通的 Java 接口,用 @WebService 注解来标记它。

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// @WebService 指定这是一个 WebService 接口
@WebService
// @SOAPBinding.Style.RPC 表示使用 RPC 风格,这是默认的
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface HelloWorldService {
    // @WebMethod 指定这是一个对外暴露的方法
    @WebMethod
    String sayHello(String name);
}

步骤 2:创建服务实现类

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

这个类实现了上面的接口。

import javax.jws.WebService;
// @WebService(endpointInterface = "com.example.HelloWorldService") 
// 指定实现的接口,这是最佳实践
@WebService(endpointInterface = "com.example.jaxws.HelloWorldService")
public class HelloWorldServiceImpl implements HelloWorldService {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
}

步骤 3:发布服务

你可以通过一个简单的 Java main 方法来发布这个服务,服务会发布在指定的 URL 上。

import javax.xml.ws.Endpoint;
public class HelloWorldPublisher {
    public static void main(String[] args) {
        // 定义服务的发布地址
        String address = "http://localhost:8888/ws/hello";
        // 创建服务实现类的实例
        HelloWorldService helloWorldService = new HelloWorldServiceImpl();
        // 发布服务
        Endpoint.publish(address, helloWorldService);
        System.out.println("WebService is published at: " + address);
    }
}

步骤 4:测试服务

  1. 运行 HelloWorldPublishermain 方法。
  2. 打开浏览器,访问 http://localhost:8888/ws/hello?wsdl
  3. 如果看到一堆 XML 代码(这就是 WSDL 文件),说明服务发布成功。

如何生成客户端?

你可以使用 JDK 自带的 wsimport 工具来生成客户端代码。

打开命令行,执行以下命令:

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

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

使用生成的客户端:

public class HelloWorldClient {
    public static void main(String[] args) {
        // 创建服务实例,通过生成的 Service 类
        HelloWorldService_Service service = new HelloWorldService_Service();
        // 获取服务端口,通过生成的 HelloWorldService 接口
        HelloWorldService helloService = service.getHelloWorldServicePort();
        // 调用远程方法
        String response = helloService.sayHello("World");
        System.out.println("Response from WebService: " + response);
    }
}

使用 JAX-RS (RESTful REST)

这种方式更现代,更灵活,是目前 Web 开发的主流,我们以 Jersey 作为实现框架为例。

准备环境

你需要添加 Jersey 的依赖,如果你使用 Maven,在 pom.xml 中添加:

<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-jackson</artifactId>
        <version>2.39</version>
    </dependency>
</dependencies>

创建服务端

步骤 1:创建资源类

这个类相当于 MVC 中的 Controller,用 @Path 注解定义 URI 路径,用 @GET, @POST 等注解定义 HTTP 方法。

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;
// @Path 定义了这个资源的 URI 路径
@Path("/greeting")
public class GreetingResource {
    // @GET 表示这个方法处理 HTTP GET 请求
    // @Path("hello") 定义了更具体的子路径
    // @Produces("text/plain") 指定返回的媒体类型是纯文本
    @GET
    @Path("hello")
    @Produces(MediaType.TEXT_PLAIN)
    public String sayHello() {
        return "Hello, Jersey!";
    }
    // 路径中可以包含参数
    @GET
    @Path("hello/{name}")
    @Produces(MediaType.TEXT_PLAIN)
    public String sayHelloToSomeone(@PathParam("name") String name) {
        return "Hello, " + name + "!";
    }
}

步骤 2:配置并部署到 Web 容器 (如 Tomcat)

RESTful 服务不能像 JAX-WS 那样用一个 main 方法发布,通常需要部署到一个 Servlet 容器(如 Tomcat, Jetty)中。

  1. 创建一个配置类:这个类用于注册你的资源。

    import org.glassfish.jersey.server.ResourceConfig;
    import javax.ws.rs.ApplicationPath;
    // @ApplicationPath 定义了所有资源的根路径
    @ApplicationPath("/api")
    public class JerseyConfig extends ResourceConfig {
        public JerseyConfig() {
            // 注册你的资源类
            register(GreetingResource.class);
        }
    }
  2. 配置 web.xml (可选,但推荐):

    <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.jaxrs</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> <!-- 与 @ApplicationPath 的值保持一致 -->
        </servlet-mapping>
    </web-app>
  3. 部署:将你的项目打包成 WAR 文件,然后部署到 Tomcat 等服务器上。

步骤 3:测试服务

启动服务器后,你可以通过浏览器或 API 工具(如 Postman)来访问。

  • 访问 http://localhost:8080/your-project-name/api/greeting/hello
    • 浏览器会显示:Hello, Jersey!
  • 访问 http://localhost:8080/your-project-name/api/greeting/hello/John
    • 浏览器会显示:Hello, John!

创建客户端 (使用 Jersey Client API)

Jersey 提供了一个强大的客户端 API,可以方便地调用其他 REST 服务。

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
public class GreetingClient {
    public static void main(String[] args) {
        // 创建客户端
        Client client = ClientBuilder.newClient();
        // 定义目标 URI
        WebTarget target = client.target("http://localhost:8080/your-project-name/api/greeting/hello/John");
        // 发送 GET 请求,并获取响应
        Response response = target.request().get();
        // 检查响应状态
        if (response.getStatus() == 200) {
            // 读取响应实体(字符串)
            String entity = response.readEntity(String.class);
            System.out.println("Response from REST service: " + entity);
        } else {
            System.out.println("Failed with HTTP error code: " + response.getStatus());
        }
        // 关闭响应和客户端
        response.close();
        client.close();
    }
}

总结与对比

特性 JAX-WS (SOAP) JAX-RS (RESTful)
协议 SOAP (Simple Object Access Protocol) HTTP
数据格式 XML (严格遵循 SOAP 规范) JSON, XML, HTML 等 (更灵活)
风格 动作导向 (RPC/Document) 资源导向
标准 Java EE 标准 Java EE 标准
优点 - 协议标准,跨语言、跨平台能力强
- 内置安全、事务等标准
- 适合企业级、金融等对稳定性要求高的场景
- 轻量级,简单易用
- 无需额外的协议层,直接使用 HTTP
- 非常适合 Web 和移动应用
- 更好的缓存支持
缺点 - 协议复杂,开销大
- 学习曲线较陡
- 开发和调试相对麻烦
- 缺乏统一的标准,不同实现可能有差异
- 安全、事务等需要自己实现或依赖其他标准
适用场景 企业内部系统集成、与旧系统集成、需要严格契约和安全性的场景。 公开 API、Web 应用、移动后端、前后端分离项目。

如何选择?

  • 如果你需要构建一个标准的、强类型的、与多种语言(.NET, PHP, Python 等)交互的企业级服务,并且对安全性、事务性有较高要求,选择 JAX-WS
  • 如果你正在开发一个现代化的 Web 应用或移动应用的后端 API,希望服务更轻量、更易于理解和扩展,并且前后端是分离的,强烈推荐 JAX-RS,目前绝大多数新的 Java Web 项目都采用 RESTful 风格。
分享:
扫描分享到社交APP
上一篇
下一篇