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

如何仅用Jetty 12 Handler.Abstract创建REST API

仅用Jetty 12 Handlers实现REST API

1. 核心逻辑:直接操作Jetty原生Request/Response

无需依赖Jersey或Servlet容器,直接通过Request解析请求的HTTP方法、路径、参数,通过Response构造响应,最终完成Callback即可实现REST接口。

2. 正确解析请求信息

你调用request.getComponents()得到的是通道状态对象,并非请求参数。以下是正确的解析方式:

获取HTTP方法

String method = request.getMethod(); // 得到GET/POST/PUT/DELETE等方法

获取请求路径

String path = request.getHttpURI().getPath(); // 提取如/shop/这类路径信息

解析URL查询参数

通过Request的getQueryParameters()方法直接获取已解码的参数:

MultiMap<String> queryParams = request.getQueryParameters();
String id = queryParams.getString("id"); // 取单个参数值
String city = queryParams.getString("city"); // 自动解码URL编码的内容(如new%20york转为new york)
List<String> countryList = queryParams.get("country"); // 处理多值参数

解析POST/PUT请求体(如JSON)

若请求体是JSON格式,需读取输入流并解析:

if ("POST".equals(method)) {
    String requestBody = request.getReader().lines().collect(Collectors.joining());
    // 可配合Jackson等JSON库转为实体类
    // ObjectMapper mapper = new ObjectMapper();
    // Shop shop = mapper.readValue(requestBody, Shop.class);
}

3. 实现REST端点路由与处理

在handle方法中,根据请求路径和HTTP方法分支处理不同端点:

class RESTHandler extends Handler.Abstract {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Override
    public boolean handle(Request request, Response response, Callback callback) {
        String method = request.getMethod();
        String path = request.getHttpURI().getPath();

        try {
            // 处理GET /shop/ 端点
            if ("GET".equals(method) && "/shop/".equals(path)) {
                handleShopGet(request, response);
            }
            // 处理POST /shop/ 端点
            else if ("POST".equals(method) && "/shop/".equals(path)) {
                handleShopPost(request, response);
            }
            // 404 未找到端点
            else {
                response.setStatus(HttpStatus.NOT_FOUND_404);
                response.getWriter().write("Endpoint not found");
            }
        } catch (IOException e) {
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR_500);
            try {
                response.getWriter().write("Server error: " + e.getMessage());
            } catch (IOException ex) {
                // 忽略写入错误,确保后续回调执行
            }
        } finally {
            // 必须调用callback,通知Jetty请求处理完成
            callback.succeeded();
        }
        return true;
    }

    private void handleShopGet(Request request, Response response) throws IOException {
        MultiMap<String> queryParams = request.getQueryParameters();
        Shop shop = new Shop(queryParams.getString("id"), queryParams.getString("city"), queryParams.getString("country"));

        // 设置响应为JSON格式
        response.getHeaders().add(HttpHeader.CONTENT_TYPE, "application/json");
        OBJECT_MAPPER.writeValue(response.getOutputStream(), shop);
    }

    private void handleShopPost(Request request, Response response) throws IOException {
        Shop newShop = OBJECT_MAPPER.readValue(request.getInputStream(), Shop.class);
        // 此处可添加数据持久化逻辑

        response.setStatus(HttpStatus.CREATED_201);
        response.getHeaders().add(HttpHeader.CONTENT_TYPE, "application/json");
        OBJECT_MAPPER.writeValue(response.getOutputStream(), newShop);
    }

    // 模拟实体类
    private static class Shop {
        public String id;
        public String city;
        public String country;

        public Shop() {} // Jackson解析需要无参构造

        public Shop(String id, String city, String country) {
            this.id = id;
            this.city = city;
            this.country = country;
        }
    }
}

4. 关键注意事项

  • 必须完成Callback:无论请求成功或失败,都要调用callback.succeeded()或callback.failed(Throwable),否则Jetty会一直等待请求结束,造成连接泄漏。
  • 响应头配置:返回JSON时需设置Content-Type: application/json,保证客户端正确解析响应。
  • 异常捕获:处理IO异常并设置对应HTTP状态码,避免未处理异常导致请求挂起。

5. 注册Handler到Jetty服务器

最后将自定义的RESTHandler注册到Jetty服务:

public static void main(String[] args) throws Exception {
    Server server = new Server(8080);
    server.setHandler(new RESTHandler());
    server.start();
    server.join();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 03:57:33