新浪微博作為國內主流社交平台,其開放平台提供基於 OAuth 2.0 的 API,支持第三方應用發布微博、上傳圖片、獲取用戶信息等。本文將從零開始,完整演示 Java 端如何實現:授權碼模式獲取 Access Token → 上傳圖片獲取 media_id → 發布帶圖微博 的全流程,代碼結構清晰,可直接落地生產。
App Key(client_id)與 App Secret(client_secret)redirect_uri 一致,需公網可訪問)<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>
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 參數。
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)。
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 生命周期、嚴格校驗上傳素材、做好異常重試與限流防護。掌握此流程,即可快速接入微博分享、營銷自動化、內容分發等業務場景。