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

如何用Java的Jetty请求复现指定curl命令?

问题:Jetty调用Lightspeed OAuth获取AccessToken失败

参考的可正常运行curl命令

curl -F 'client_id={client id}' \
-F 'client_secret={client secret}' \
-F 'code={temporary token}' \
-F 'grant_type=authorization_code' \
https://cloud.lightspeedapp.com/oauth/access_token.php

我的Jetty代码尝试

尝试1:使用MultiPartContentProvider

URIBuilder uriBuilder = new URIBuilder("https://cloud.lightspeedapp.com")
  .setPath("/oauth/access_token.php");

MultiPartContentProvider contentProvider = new MultiPartContentProvider();
contentProvider.addFieldPart("grant_type", new StringContentProvider("authorization_code"), null);
contentProvider.addFieldPart("client_id", new StringContentProvider(lightspeedRId), null);
contentProvider.addFieldPart("client_secret", new StringContentProvider(lightspeedRSecret), null);
contentProvider.addFieldPart("code", new StringContentProvider(temporaryToken), null);
contentProvider.close();

Request request = httpClient.POST(uriBuilder.build())
  .content(contentProvider)
  .header("Content-Type", "multipart/form-data");

尝试2:使用FormContentProvider

Fields fields = new Fields();
fields.put("grant_type", "authorization_code");
fields.put("client_id", lightspeedRId);
fields.put("client_secret", lightspeedRSecret);
fields.put("code",temporaryToken);
FormContentProvider contentProvider = new FormContentProvider(fields);

以上两种方式均无法正常调用API,求修复方案。


解决方案

核心问题分析

curl的-F参数在没有指定文件时,实际会发送application/x-www-form-urlencoded类型的请求(而非multipart/form-data),这是常见混淆点。你的代码存在两个关键遗漏:

  1. 未执行请求发送操作(缺少send()调用)
  2. 未正确处理请求执行的异常与响应结果

修正后的FormContentProvider代码

// 构建请求URI
URIBuilder uriBuilder = new URIBuilder("https://cloud.lightspeedapp.com")
        .setPath("/oauth/access_token.php");

// 构建表单参数(确保变量已替换为真实有效值)
Fields fields = new Fields();
fields.put("grant_type", "authorization_code");
fields.put("client_id", lightspeedRId);
fields.put("client_secret", lightspeedRSecret);
fields.put("code", temporaryToken);

// 创建表单内容提供者
FormContentProvider contentProvider = new FormContentProvider(fields);

try {
    // 初始化HttpClient(若未初始化)
    httpClient.start();
    
    // 发送请求并获取响应
    ContentResponse response = httpClient.POST(uriBuilder.build())
            .content(contentProvider)
            // FormContentProvider会自动设置正确的Content-Type,无需手动指定
            .send();

    // 处理响应结果
    if (response.getStatus() == 200) {
        String responseBody = response.getContentAsString();
        System.out.println("获取AccessToken成功:" + responseBody);
        // 可在此处用JSON库解析响应内容
    } else {
        System.err.println("请求失败,状态码:" + response.getStatus());
        System.err.println("响应详情:" + response.getContentAsString());
    }
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
} finally {
    // 释放HttpClient资源
    try {
        httpClient.stop();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

为什么MultiPartContentProvider不可用?

Lightspeed的OAuth接口仅接受application/x-www-form-urlencoded类型请求,curl的-F是简化写法,无文件时会自动降级为表单编码,并非真正的multipart/form-data请求,所以MultiPart方式不符合接口要求。

额外检查点

  • 确认lightspeedRId、lightspeedRSecret、temporaryToken均为有效值,无空值或格式错误
  • 检查HttpClient是否正确初始化(必须调用start()方法)
  • 查看异常日志,明确是连接失败、参数错误还是权限类问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:55:21