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

Java 6 EE中基于HttpUrlConnection实现Client Credentials Bearer令牌生成

Java 6 EE 实现 Client Credentials 模式获取 OAuth2 令牌

核心实现代码

Client Credentials 模式的令牌请求需向授权服务器的 token 端点发送 POST 表单请求,以下是基于HttpUrlConnection的完整实现,依赖兼容 Java 6 的org.json包解析响应:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONObject;

public class OAuth2TokenFetcher {
    // 替换为授权服务器的token端点URL
    private static final String TOKEN_ENDPOINT = "https://your-auth-server/token";
    // 替换为你的client_id和client_secret
    private static final String CLIENT_ID = "your-client-id";
    private static final String CLIENT_SECRET = "your-client-secret";
    
    // 缓存令牌与过期时间,避免重复请求
    private static String cachedAccessToken;
    private static long tokenExpiryTimestamp;

    public static String getValidToken() throws IOException {
        // 检查缓存令牌是否有效(提前1分钟刷新,规避请求过程中令牌过期风险)
        if (cachedAccessToken != null && System.currentTimeMillis() < tokenExpiryTimestamp - 60000) {
            return cachedAccessToken;
        }
        
        // 构建表单请求参数
        Map<String, String> formParams = new HashMap<String, String>();
        formParams.put("grant_type", "client_credentials");
        formParams.put("client_id", CLIENT_ID);
        formParams.put("client_secret", CLIENT_SECRET);
        
        // 编码表单数据
        StringBuilder postData = new StringBuilder();
        for (Map.Entry<String, String> entry : formParams.entrySet()) {
            if (postData.length() != 0) postData.append('&');
            postData.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            postData.append('=');
            postData.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
        }
        byte[] postDataBytes = postData.toString().getBytes("UTF-8");
        
        // 建立连接并发送请求
        URL url = new URL(TOKEN_ENDPOINT);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
        conn.setDoOutput(true);
        
        OutputStream os = conn.getOutputStream();
        os.write(postDataBytes);
        os.flush();
        os.close();
        
        // 读取并解析响应
        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
        StringBuilder response = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            response.append(line);
        }
        br.close();
        conn.disconnect();
        
        JSONObject tokenResponse = new JSONObject(response.toString());
        cachedAccessToken = tokenResponse.getString("access_token");
        int expiresInSeconds = tokenResponse.getInt("expires_in");
        // 计算令牌过期时间戳
        tokenExpiryTimestamp = System.currentTimeMillis() + (expiresInSeconds * 1000L);
        
        return cachedAccessToken;
    }
}

关键细节说明

  • 令牌缓存:通过静态变量实现简单缓存,避免频繁调用授权服务器;提前1分钟触发刷新,防止请求过程中令牌刚好过期
  • 多线程适配:如果是多线程环境,需在getValidToken()方法添加synchronized修饰符,或使用并发安全的容器存储缓存数据
  • 依赖处理:Java 6无内置JSON解析工具,需引入org.json包(推荐版本20090211,完全兼容Java 6),Maven依赖如下:
    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
        <version>20090211</version>
    </dependency>
    
  • Basic认证适配:若授权服务器要求将client_id和client_secret做Base64编码后放在Authorization头,需添加以下代码:
    // 需引入commons-codec 1.9(兼容Java 6)的Base64工具类
    String authPair = CLIENT_ID + ":" + CLIENT_SECRET;
    String encodedAuth = Base64.encodeBase64String(authPair.getBytes("UTF-8"));
    conn.setRequestProperty("Authorization", "Basic " + encodedAuth);
    
  • HTTPS证书处理:若授权服务器使用自签名证书,需将证书导入Java 6的信任库,或添加自定义信任管理器绕过证书校验(仅测试环境使用)

异常处理建议

实际项目中需捕获IOException、JSONException等异常,根据业务场景实现重试逻辑或错误告警,避免因令牌获取失败导致业务中断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:06:00