首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 實現新浪微博 OAuth 2.0 認證與圖文發布完整實戰

     編輯:Java 相關知識

項目背景

新浪微博作為國內主流社交平台,其開放平台提供基於 OAuth 2.0 的 API,支持第三方應用發布微博、上傳圖片、獲取用戶信息等。本文將從零開始,完整演示 Java 端如何實現:授權碼模式獲取 Access Token → 上傳圖片獲取 media_id → 發布帶圖微博 的全流程,代碼結構清晰,可直接落地生產。

準備工作

  1. 在 微博開放平台 創建應用,獲取 App Key(client_id)與 App Secret(client_secret)
  2. 配置授權回調頁(需與代碼中 redirect_uri 一致,需公網可訪問)
  3. 申請「發布微博」高級權限(需通過審核)

核心依賴

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

步驟一:構建授權 URL,引導用戶登錄授權

public class WeiboOAuthConfig {
    public static final String CLIENT_ID = "你的App Key";
    public static final String CLIENT_SECRET = "你的App Secret";
    public static final String REDIRECT_URI = "https://yourdomain.com/callback";
    public static final String AUTH_URL = "https://api.weibo.com/oauth2/authorize";
    public static final String TOKEN_URL = "https://api.weibo.com/oauth2/access_token";
    public static final String UPLOAD_URL = "https://api.weibo.com/2/statuses/upload.json";
    public static final String UPLOAD_PIC_URL = "https://api.weibo.com/2/statuses/upload_url_text.json";
}

public String buildAuthUrl() {
    return WeiboOAuthConfig.AUTH_URL + "?client_id=" + WeiboOAuthConfig.CLIENT_ID
            + "&redirect_uri=" + URLEncoder.encode(WeiboOAuthConfig.REDIRECT_URI, StandardCharsets.UTF_8)
            + "&response_type=code&scope=all";
}

用戶在瀏覽器打開該 URL,登錄並授權後,微博會重定向到 redirect_uri?code=xxx,你的後端需接收 code 參數。

步驟二:用授權碼換取 Access Token

public class TokenResponse {
    private String access_token;
    private String expires_in;
    private String uid;
    private String refresh_token;
    // getter/setter 省略
}

public TokenResponse getAccessToken(String code) throws IOException {
    try (CloseableHttpClient client = HttpClients.createDefault()) {
        HttpPost post = new HttpPost(WeiboOAuthConfig.TOKEN_URL);
        List<NameValuePair> params = Arrays.asList(
                new BasicNameValuePair("client_id", WeiboOAuthConfig.CLIENT_ID),
                new BasicNameValuePair("client_secret", WeiboOAuthConfig.CLIENT_SECRET),
                new BasicNameValuePair("grant_type", "authorization_code"),
                new BasicNameValuePair("redirect_uri", WeiboOAuthConfig.REDIRECT_URI),
                new BasicNameValuePair("code", code)
        );
        post.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));
        String json = client.execute(post, new BasicResponseHandler());
        return new Gson().fromJson(json, TokenResponse.class);
    }
}

注意:Access Token 有效期通常為 30 天,需持久化存儲(Redis/DB)並實現定時刷新機制(使用 refresh_token)。

步驟三:上傳圖片獲取 media_id

public String uploadImage(String accessToken, File imageFile) throws IOException {
    try (CloseableHttpClient client = HttpClients.createDefault()) {
        HttpPost post = new HttpPost(WeiboOAuthConfig.UPLOAD_PIC_URL + "?access_token=" + accessToken);
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addBinaryBody("pic", imageFile, ContentType.APPLICATION_OCTET_STREAM, imageFile.getName());
        post.setEntity(builder.build());
        String json = client.execute(post, new BasicResponseHandler());
        JsonObject jo = JsonParser.parseString(json).getAsJsonObject();
        return jo.get("media_id").getAsString(); // 關鍵:發布微博時需此 ID
    }
}

步驟四:發布帶圖微博

public String postStatus(String accessToken, String status, String mediaId) throws IOException {
    try (CloseableHttpClient client = HttpClients.createDefault()) {
        HttpPost post = new HttpPost(WeiboOAuthConfig.UPLOAD_URL);
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("access_token", accessToken));
        params.add(new BasicNameValuePair("status", status));
        if (mediaId != null) {
            params.add(new BasicNameValuePair("media_ids", mediaId)); // 支持多圖,逗號分隔
        }
        post.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));
        return client.execute(post, new BasicResponseHandler());
    }
}

完整業務流程串聯示例

@Service
public class WeiboPublishService {
    // 注入配置、HttpClient、Token存儲服務...

    public void publishWeiboWithImage(String authCode, String text, File image) {
        // 1. 換取 Token
        TokenResponse token = getAccessToken(authCode);
        tokenStorage.save(token.getUid(), token);

        // 2. 上傳圖片
        String mediaId = uploadImage(token.getAccess_token(), image);

        // 3. 發布微博
        String result = postStatus(token.getAccess_token(), text, mediaId);
        log.info("微博發布結果:{}", result);
    }
}

常見坑點與最佳實踐

問題解決方案
Access Token 過期定時任務檢查 expires_in,提前刷新;捕獲 error_code=21327 觸發刷新重試
圖片大小/格式限制預校驗:<5MB、支持 jpg/png/gif、長寬 < 2000px
發布頻率限制同一用戶/應用/小時有配額,接入令牌桶限流(Resilience4j)
中文內容編碼全鏈路 UTF-8,URLEncoder.encode(status, "UTF-8") 處理特殊字符
HTTPS 證書驗證生產環境勿關閉 SSL 驗證,若測試需忽略,自定義 SSLContext

總結

本文提供了從 OAuth 授權、Token 管理、圖片上傳到微博發布的完整 Java 實現方案。代碼模組化程度高,核心邏輯與配置分離,易於在 Spring Boot 等框架中集成。關鍵在於:妥善管理 Token 生命周期、嚴格校驗上傳素材、做好異常重試與限流防護。掌握此流程,即可快速接入微博分享、營銷自動化、內容分發等業務場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved