mirror of
https://github.com/czp3009/bilibili-api.git
synced 2025-02-19 20:50:28 +08:00
使 SimpleCookieJar 支持并发读写
This commit is contained in:
parent
21e106030d
commit
a182d56fc6
@ -24,13 +24,18 @@ public class ErrorResponseConverterInterceptor implements Interceptor {
|
||||
JsonObject jsonObject = InterceptorHelper.getJsonInBody(response);
|
||||
JsonElement code = jsonObject.get("code");
|
||||
//code 字段不存在
|
||||
if (code == null) {
|
||||
if (code == null || code.isJsonNull()) {
|
||||
return response;
|
||||
}
|
||||
//code 为 0
|
||||
if (code.getAsInt() == ServerErrorCode.Common.OK) {
|
||||
try {
|
||||
if (code.getAsInt() == ServerErrorCode.Common.OK) {
|
||||
return response;
|
||||
}
|
||||
} catch (NumberFormatException e) { //如果 code 不是数字的话直接返回
|
||||
return response;
|
||||
}
|
||||
|
||||
//打印 body
|
||||
LOGGER.error("Get error response below: \n{}",
|
||||
new GsonBuilder()
|
||||
|
@ -2,6 +2,7 @@ package com.hiczp.bilibili.api.web;
|
||||
|
||||
import com.hiczp.bilibili.api.BaseUrlDefinition;
|
||||
import com.hiczp.bilibili.api.interceptor.AddFixedHeadersInterceptor;
|
||||
import com.hiczp.bilibili.api.interceptor.ErrorResponseConverterInterceptor;
|
||||
import com.hiczp.bilibili.api.web.cookie.SimpleCookieJar;
|
||||
import com.hiczp.bilibili.api.web.live.LiveService;
|
||||
import okhttp3.Cookie;
|
||||
@ -53,7 +54,8 @@ public class BilibiliWebAPI {
|
||||
.cookieJar(cookieJar)
|
||||
.addInterceptor(new AddFixedHeadersInterceptor(
|
||||
"User-Agent", browserProperties.getUserAgent()
|
||||
));
|
||||
))
|
||||
.addInterceptor(new ErrorResponseConverterInterceptor());
|
||||
|
||||
interceptors.forEach(okHttpClientBuilder::addInterceptor);
|
||||
|
||||
|
@ -4,41 +4,49 @@ import okhttp3.Cookie;
|
||||
import okhttp3.CookieJar;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SimpleCookieJar implements CookieJar {
|
||||
private Map<String, List<Cookie>> cookiesMap;
|
||||
private final Map<String, List<Cookie>> cookiesMap;
|
||||
|
||||
public SimpleCookieJar() {
|
||||
cookiesMap = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
public SimpleCookieJar(Map<String, List<Cookie>> cookiesMap) {
|
||||
this.cookiesMap = new ConcurrentHashMap<>(cookiesMap);
|
||||
public SimpleCookieJar(@Nonnull Map<String, List<Cookie>> cookiesMap) {
|
||||
this();
|
||||
cookiesMap.forEach((domain, cookies) ->
|
||||
this.cookiesMap.put(domain, new Vector<>(cookies))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
|
||||
cookies.forEach(cookie -> {
|
||||
String domain = cookie.domain();
|
||||
List<Cookie> savedCookies = cookiesMap.get(domain);
|
||||
if (savedCookies == null) {
|
||||
savedCookies = new ArrayList<>();
|
||||
savedCookies.add(cookie);
|
||||
cookiesMap.put(domain, savedCookies);
|
||||
} else {
|
||||
for (Cookie savedCookie : savedCookies) {
|
||||
if (savedCookie.name().equals(cookie.name())) {
|
||||
savedCookies.remove(savedCookie);
|
||||
break;
|
||||
}
|
||||
List<Cookie> savedCookies;
|
||||
synchronized (cookiesMap) {
|
||||
savedCookies = cookiesMap.get(domain);
|
||||
if (savedCookies == null) {
|
||||
savedCookies = new Vector<>();
|
||||
savedCookies.add(cookie);
|
||||
cookiesMap.put(domain, savedCookies);
|
||||
return;
|
||||
}
|
||||
savedCookies.add(cookie);
|
||||
}
|
||||
for (int i = savedCookies.size() - 1; i >= 0; i--) {
|
||||
Cookie current = savedCookies.get(i);
|
||||
if (current.name().equals(cookie.name())) {
|
||||
savedCookies.remove(current);
|
||||
}
|
||||
}
|
||||
savedCookies.add(cookie);
|
||||
});
|
||||
}
|
||||
|
||||
@ -47,13 +55,15 @@ public class SimpleCookieJar implements CookieJar {
|
||||
return getCookiesForHost(url.host());
|
||||
}
|
||||
|
||||
public List<Cookie> getCookiesForHost(String host) {
|
||||
public List<Cookie> getCookiesForHost(@Nonnull String host) {
|
||||
List<Cookie> cookieList = new ArrayList<>();
|
||||
cookiesMap.forEach((domain, cookies) -> {
|
||||
if (host.endsWith(domain)) {
|
||||
//移除过期的 cookies
|
||||
for (int i = cookies.size() - 1; i >= 0; i--) {
|
||||
if (cookies.get(i).expiresAt() < System.currentTimeMillis()) {
|
||||
cookies.remove(i);
|
||||
Cookie current = cookies.get(i);
|
||||
if (current.expiresAt() < System.currentTimeMillis()) {
|
||||
cookies.remove(current);
|
||||
}
|
||||
}
|
||||
cookieList.addAll(cookies);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.hiczp.bilibili.api.web.live;
|
||||
|
||||
import com.hiczp.bilibili.api.web.live.entity.SendHeartBeatResponseEntity;
|
||||
import com.hiczp.bilibili.api.web.live.entity.UserInfoEntity;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Query;
|
||||
@ -15,4 +16,14 @@ public interface LiveService {
|
||||
default Call<SendHeartBeatResponseEntity> sendHeartBeat() {
|
||||
return sendHeartBeat(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
//获取用户信息
|
||||
//成功时, code 为 "REPONSE_OK"
|
||||
//未登录时返回 500
|
||||
@GET("User/getUserInfo")
|
||||
Call<UserInfoEntity> getUserInfo(@Query("ts") long timestamp);
|
||||
|
||||
default Call<UserInfoEntity> getUserInfo() {
|
||||
return getUserInfo(System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,191 @@
|
||||
package com.hiczp.bilibili.api.web.live.entity;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class UserInfoEntity {
|
||||
/**
|
||||
* code : REPONSE_OK
|
||||
* msg : ok
|
||||
* data : {"uname":"czp3009","face":"http://i2.hdslb.com/bfs/face/4f65e79399ad5a1bf3f877851b2f819d5870b494.jpg","silver":22528,"gold":0,"achieve":135,"vip":0,"svip":0,"user_level":25,"user_next_level":26,"user_intimacy":926000,"user_next_intimacy":10000000,"user_level_rank":">50000","billCoin":699}
|
||||
*/
|
||||
|
||||
@SerializedName("code")
|
||||
private String code;
|
||||
@SerializedName("msg")
|
||||
private String msg;
|
||||
@SerializedName("data")
|
||||
private Data data;
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public Data getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static class Data {
|
||||
/**
|
||||
* uname : czp3009
|
||||
* face : http://i2.hdslb.com/bfs/face/4f65e79399ad5a1bf3f877851b2f819d5870b494.jpg
|
||||
* silver : 22528
|
||||
* gold : 0
|
||||
* achieve : 135
|
||||
* vip : 0
|
||||
* svip : 0
|
||||
* user_level : 25
|
||||
* user_next_level : 26
|
||||
* user_intimacy : 926000
|
||||
* user_next_intimacy : 10000000
|
||||
* user_level_rank : >50000
|
||||
* billCoin : 699
|
||||
*/
|
||||
|
||||
@SerializedName("uname")
|
||||
private String uname;
|
||||
@SerializedName("face")
|
||||
private String face;
|
||||
@SerializedName("silver")
|
||||
private int silver;
|
||||
@SerializedName("gold")
|
||||
private int gold;
|
||||
@SerializedName("achieve")
|
||||
private int achieve;
|
||||
@SerializedName("vip")
|
||||
private int vip;
|
||||
@SerializedName("svip")
|
||||
private int svip;
|
||||
@SerializedName("user_level")
|
||||
private int userLevel;
|
||||
@SerializedName("user_next_level")
|
||||
private int userNextLevel;
|
||||
@SerializedName("user_intimacy")
|
||||
private int userIntimacy;
|
||||
@SerializedName("user_next_intimacy")
|
||||
private int userNextIntimacy;
|
||||
@SerializedName("user_level_rank")
|
||||
private String userLevelRank;
|
||||
@SerializedName("billCoin")
|
||||
private int billCoin;
|
||||
|
||||
public String getUname() {
|
||||
return uname;
|
||||
}
|
||||
|
||||
public void setUname(String uname) {
|
||||
this.uname = uname;
|
||||
}
|
||||
|
||||
public String getFace() {
|
||||
return face;
|
||||
}
|
||||
|
||||
public void setFace(String face) {
|
||||
this.face = face;
|
||||
}
|
||||
|
||||
public int getSilver() {
|
||||
return silver;
|
||||
}
|
||||
|
||||
public void setSilver(int silver) {
|
||||
this.silver = silver;
|
||||
}
|
||||
|
||||
public int getGold() {
|
||||
return gold;
|
||||
}
|
||||
|
||||
public void setGold(int gold) {
|
||||
this.gold = gold;
|
||||
}
|
||||
|
||||
public int getAchieve() {
|
||||
return achieve;
|
||||
}
|
||||
|
||||
public void setAchieve(int achieve) {
|
||||
this.achieve = achieve;
|
||||
}
|
||||
|
||||
public int getVip() {
|
||||
return vip;
|
||||
}
|
||||
|
||||
public void setVip(int vip) {
|
||||
this.vip = vip;
|
||||
}
|
||||
|
||||
public int getSvip() {
|
||||
return svip;
|
||||
}
|
||||
|
||||
public void setSvip(int svip) {
|
||||
this.svip = svip;
|
||||
}
|
||||
|
||||
public int getUserLevel() {
|
||||
return userLevel;
|
||||
}
|
||||
|
||||
public void setUserLevel(int userLevel) {
|
||||
this.userLevel = userLevel;
|
||||
}
|
||||
|
||||
public int getUserNextLevel() {
|
||||
return userNextLevel;
|
||||
}
|
||||
|
||||
public void setUserNextLevel(int userNextLevel) {
|
||||
this.userNextLevel = userNextLevel;
|
||||
}
|
||||
|
||||
public int getUserIntimacy() {
|
||||
return userIntimacy;
|
||||
}
|
||||
|
||||
public void setUserIntimacy(int userIntimacy) {
|
||||
this.userIntimacy = userIntimacy;
|
||||
}
|
||||
|
||||
public int getUserNextIntimacy() {
|
||||
return userNextIntimacy;
|
||||
}
|
||||
|
||||
public void setUserNextIntimacy(int userNextIntimacy) {
|
||||
this.userNextIntimacy = userNextIntimacy;
|
||||
}
|
||||
|
||||
public String getUserLevelRank() {
|
||||
return userLevelRank;
|
||||
}
|
||||
|
||||
public void setUserLevelRank(String userLevelRank) {
|
||||
this.userLevelRank = userLevelRank;
|
||||
}
|
||||
|
||||
public int getBillCoin() {
|
||||
return billCoin;
|
||||
}
|
||||
|
||||
public void setBillCoin(int billCoin) {
|
||||
this.billCoin = billCoin;
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ import java.nio.file.Paths;
|
||||
SendBulletScreenTest.class,
|
||||
SecurityHelperTest.class,
|
||||
AuthenticatorTest.class,
|
||||
WebAPITest.class,
|
||||
LogoutTest.class
|
||||
})
|
||||
public class RuleSuite {
|
||||
|
33
src/test/java/com/hiczp/bilibili/api/test/WebAPITest.java
Normal file
33
src/test/java/com/hiczp/bilibili/api/test/WebAPITest.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.hiczp.bilibili.api.test;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.hiczp.bilibili.api.web.BilibiliWebAPI;
|
||||
import com.hiczp.bilibili.api.web.live.entity.UserInfoEntity;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class WebAPITest {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(WebAPITest.class);
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
private BilibiliWebAPI bilibiliWebAPI;
|
||||
|
||||
public WebAPITest() {
|
||||
try {
|
||||
this.bilibiliWebAPI = Config.getBilibiliAPI().getBilibiliWebAPI();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUserInfo() throws IOException {
|
||||
UserInfoEntity userInfoEntity = bilibiliWebAPI.getLiveService().getUserInfo()
|
||||
.execute()
|
||||
.body();
|
||||
LOGGER.info("User info below: \n{}", GSON.toJson(userInfoEntity));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user