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

Java POST请求application/x-www-form-urlencoded获取Token遇400错误排查

解决Java调用Token API返回400错误及相关问题

看起来你的代码里有几个明显的问题导致了400错误,还有一些细节处理不当引发了额外异常,咱们一步步来梳理修正:

1. 重复操作输出流导致请求体异常

你的代码同时用了OutputStreamWriter和直接获取OutputStream来操作请求体,这会导致输出流被重复处理,请求体要么没正确发送,要么内容不完整:

OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
wr.write(urlParameters); 
// 下面这段重复操作会破坏之前的写入,导致请求体异常
OutputStream os = con.getOutputStream();
os.flush();
os.close();

正确做法是只用一种方式写入请求体,写完后统一完成flush和close操作。

2. 调试信息错误

代码里打印了Sending 'GET' request,但你明明用的是POST请求,这会误导调试;而且打印的是os(输出流对象),这毫无意义,应该打印实际请求的URL。

3. HTTPS连接配置问题

出现sun.net.www.protocol.https.DelegateHttpsURLConnection错误,通常和HTTPS证书验证有关——如果目标API用的是自签名证书,Java默认会拒绝连接,需要调整证书信任配置。

修正后的完整代码

BufferedReader in = null;
String response = "";
String urlParameters = "grant_type=client_credentials";
try {
    URL obj = new URL("你的API实际请求URL");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    
    // 设置请求方法为POST
    con.setRequestMethod("POST");
    // 规范设置请求头(注意参数名大小写)
    con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    // 重点:Basic后面的value必须是 clientId:clientSecret 的Base64编码值
    con.setRequestProperty("Authorization", "Basic 你的Base64编码凭证");
    
    // 允许输出请求体
    con.setDoOutput(true);
    
    // 用try-with-resources自动管理流,避免手动关闭的遗漏
    try (OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream())) {
        wr.write(urlParameters);
        wr.flush();
    }
    
    // 获取响应码并打印正确的调试信息
    int responseCode = con.getResponseCode();
    System.out.println("\nSending 'POST' request to URL : " + obj);
    System.out.println("Response Code: " + responseCode);
    
    // 用StringBuilder拼接响应内容,比直接String拼接更高效
    StringBuilder responseBuilder = new StringBuilder();
    in = new BufferedReader(new InputStreamReader(con.getInputStream()));
    String inputLine;
    while ((inputLine = in.readLine()) != null) {
        responseBuilder.append(inputLine);
    }
    response = responseBuilder.toString();
    System.out.println("Response Body: " + response);
    
} catch (IOException e) {
    // 关键:400错误时要读取错误流,获取API返回的具体错误信息
    if (con != null) {
        try (BufferedReader errorReader = new BufferedReader(new InputStreamReader(con.getErrorStream()))) {
            String errorLine;
            StringBuilder errorBuilder = new StringBuilder();
            while ((errorLine = errorReader.readLine()) != null) {
                errorBuilder.append(errorLine);
            }
            System.err.println("API Error Response: " + errorBuilder.toString());
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    e.printStackTrace();
} finally {
    if (in != null) {
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

额外注意事项

  • Authorization头正确性:Basic后面的value必须是client_id:client_secret的Base64编码字符串,你可以用Java自带的工具类生成:
    String credentials = "你的clientId:你的clientSecret";
    String base64Credentials = Base64.getEncoder().encodeToString(credentials.getBytes(StandardCharsets.UTF_8));
    
  • HTTPS证书处理:如果是自签名证书,测试环境可以临时跳过验证(生产环境绝对禁用):
    // 临时跳过HTTPS证书验证(仅测试用)
    TrustManager[] trustAllCerts = new TrustManager[]{
        new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
        }
    };
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    HostnameVerifier allHostsValid = (hostname, session) -> true;
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    
  • 请求体编码:如果参数值包含特殊字符,需要用URLEncoder.encode()对参数值单独编码,避免格式错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 07:42:45