You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Jersey JAX-RS实现REST多资源类的技术咨询

基于Jersey JAX-RS实现多REST资源类的配置与开发指南

没问题,我来一步步教你怎么用Jersey JAX-RS搞定Namenode和Datanode这类多资源类的配置与开发,完美适配你提到的JDK HTTP服务器场景。

1. 先搞定依赖配置

如果用Maven管理项目,直接在pom.xml里添加以下核心依赖——包括Jersey的核心模块、JDK HttpServer适配模块,还有JSON处理的依赖(毕竟你接口返回的是JSON格式):

<dependencies>
    <!-- Jersey核心服务模块 -->
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
        <version>2.41</version> <!-- 建议用最新稳定版 -->
    </dependency>
    <!-- JAX-RS API规范 -->
    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>javax.ws.rs-api</artifactId>
        <version>2.1.1</version>
    </dependency>
    <!-- Jersey适配JDK原生HttpServer的模块 -->
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-jdk-http</artifactId>
        <version>2.41</version>
    </dependency>
    <!-- JSON序列化/反序列化支持(Jackson实现) -->
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.41</version>
    </dependency>
</dependencies>

2. 实现你的资源接口与类

先把你给出的Namenode接口补全并实现,Datanode类也按照同样的方式定义:

Namenode接口与实现类

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.List;

@Path(Namenode.PATH)
public interface Namenode {
    static final String PATH = "/namenode";

    @GET
    @Path("/list/")
    @Produces(MediaType.APPLICATION_JSON)
    List<String> list(@QueryParam("prefix") String prefix);

    @GET
    @Path("/{name}")
    @Produces(MediaType.APPLICATION_JSON)
    List<String> read(@PathParam("name") String name);
}

// 具体业务实现类
public class NamenodeImpl implements Namenode {
    @Override
    public List<String> list(String prefix) {
        // 这里替换成你的实际业务逻辑,比如从HDFS元数据获取文件列表
        return prefix == null ? List.of("file1.txt", "dir1") : List.of(prefix + "_file.txt");
    }

    @Override
    public List<String> read(String name) {
        // 模拟读取文件内容的逻辑
        return List.of("line1 of " + name, "line2 of " + name);
    }
}

Datanode类示例

假设Datanode有心跳和获取块列表的接口,定义如下:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.List;

@Path(Datanode.PATH)
public class Datanode {
    static final String PATH = "/datanode";

    @GET
    @Path("/heartbeat")
    @Produces(MediaType.APPLICATION_JSON)
    String heartbeat() {
        return "{\"status\":\"alive\"}";
    }

    @GET
    @Path("/blocks")
    @Produces(MediaType.APPLICATION_JSON)
    List<String> getBlocks() {
        // 模拟返回数据块列表
        return List.of("block_001", "block_002");
    }
}

3. 配置Jersey应用类

创建一个继承ResourceConfig的类,用来注册所有的资源类和必要的功能组件:

import org.glassfish.jersey.server.ResourceConfig;

public class HadoopRestApp extends ResourceConfig {
    public HadoopRestApp() {
        // 注册Namenode的实现类和Datanode类
        register(NamenodeImpl.class);
        register(Datanode.class);
        // 注册Jackson JSON序列化/反序列化提供者
        register(org.glassfish.jersey.jackson.JacksonFeature.class);
    }
}

4. 启动JDK HTTP服务器并绑定Jersey

写一个主类,启动JDK自带的HttpServer,并把Jersey的应用绑定上去:

import com.sun.net.httpserver.HttpServer;
import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
import java.net.URI;

public class MainServer {
    public static void main(String[] args) {
        // 定义服务的基础URI,比如http://localhost:8080/api/
        URI baseUri = URI.create("http://localhost:8080/api/");
        
        // 创建JDK HttpServer并绑定Jersey应用
        HttpServer server = JdkHttpServerFactory.createHttpServer(baseUri, new HadoopRestApp());
        
        System.out.println("服务器已启动,地址:" + baseUri);
        System.out.println("可用接口:");
        System.out.println("- Namenode列表接口:GET " + baseUri + Namenode.PATH + "/list?prefix=xxx");
        System.out.println("- Namenode读取接口:GET " + baseUri + Namenode.PATH + "/{name}");
        System.out.println("- Datanode心跳接口:GET " + baseUri + Datanode.PATH + "/heartbeat");
        System.out.println("- Datanode块列表接口:GET " + baseUri + Datanode.PATH + "/blocks");
        
        // 添加关闭钩子,确保程序终止时服务器能正常关闭
        Runtime.getRuntime().addShutdownHook(new Thread(server::stop));
    }
}

5. 测试接口

启动MainServer后,用curl或者Postman来验证接口:

  • 测试Namenode的list接口:
curl http://localhost:8080/api/namenode/list?prefix=test

预期返回:["test_file.txt"]

  • 测试Namenode的read接口:
curl http://localhost:8080/api/namenode/myfile.txt

预期返回:["line1 of myfile.txt","line2 of myfile.txt"]

  • 测试Datanode的心跳接口:
curl http://localhost:8080/api/datanode/heartbeat

预期返回:{"status":"alive"}

一些关键注意事项

  • 路径冲突检查:确保Namenode和Datanode的根路径(/namenode和/datanode)完全独立,避免接口路径重叠。
  • JSON支持:必须注册JacksonFeature或者其他JSON提供者,否则Jersey无法将List等对象序列化为JSON格式。
  • 参数注解:@QueryParam和@PathParam要和接口定义的参数一一对应,避免参数绑定失败。
  • 扩展配置:如果需要添加过滤器、拦截器或者自定义异常处理,直接在HadoopRestApp的构造方法里注册对应的类即可。

内容的提问来源于stack exchange,提问作者bbk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:53:36