mirror of
https://github.com/czp3009/bilibili-api.git
synced 2025-03-21 21:00:26 +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);
|
JsonObject jsonObject = InterceptorHelper.getJsonInBody(response);
|
||||||
JsonElement code = jsonObject.get("code");
|
JsonElement code = jsonObject.get("code");
|
||||||
//code 字段不存在
|
//code 字段不存在
|
||||||
if (code == null) {
|
if (code == null || code.isJsonNull()) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
//code 为 0
|
//code 为 0
|
||||||
if (code.getAsInt() == ServerErrorCode.Common.OK) {
|
try {
|
||||||
|
if (code.getAsInt() == ServerErrorCode.Common.OK) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) { //如果 code 不是数字的话直接返回
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
//打印 body
|
//打印 body
|
||||||
LOGGER.error("Get error response below: \n{}",
|
LOGGER.error("Get error response below: \n{}",
|
||||||
new GsonBuilder()
|
new GsonBuilder()
|
||||||
|
@ -2,6 +2,7 @@ package com.hiczp.bilibili.api.web;
|
|||||||
|
|
||||||
import com.hiczp.bilibili.api.BaseUrlDefinition;
|
import com.hiczp.bilibili.api.BaseUrlDefinition;
|
||||||
import com.hiczp.bilibili.api.interceptor.AddFixedHeadersInterceptor;
|
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.cookie.SimpleCookieJar;
|
||||||
import com.hiczp.bilibili.api.web.live.LiveService;
|
import com.hiczp.bilibili.api.web.live.LiveService;
|
||||||
import okhttp3.Cookie;
|
import okhttp3.Cookie;
|
||||||
@ -53,7 +54,8 @@ public class BilibiliWebAPI {
|
|||||||
.cookieJar(cookieJar)
|
.cookieJar(cookieJar)
|
||||||
.addInterceptor(new AddFixedHeadersInterceptor(
|
.addInterceptor(new AddFixedHeadersInterceptor(
|
||||||
"User-Agent", browserProperties.getUserAgent()
|
"User-Agent", browserProperties.getUserAgent()
|
||||||
));
|
))
|
||||||
|
.addInterceptor(new ErrorResponseConverterInterceptor());
|
||||||
|
|
||||||
interceptors.forEach(okHttpClientBuilder::addInterceptor);
|
interceptors.forEach(okHttpClientBuilder::addInterceptor);
|
||||||
|
|
||||||
|
@ -4,41 +4,49 @@ import okhttp3.Cookie;
|
|||||||
import okhttp3.CookieJar;
|
import okhttp3.CookieJar;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Vector;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class SimpleCookieJar implements CookieJar {
|
public class SimpleCookieJar implements CookieJar {
|
||||||
private Map<String, List<Cookie>> cookiesMap;
|
private final Map<String, List<Cookie>> cookiesMap;
|
||||||
|
|
||||||
public SimpleCookieJar() {
|
public SimpleCookieJar() {
|
||||||
cookiesMap = new ConcurrentHashMap<>();
|
cookiesMap = new ConcurrentHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleCookieJar(Map<String, List<Cookie>> cookiesMap) {
|
public SimpleCookieJar(@Nonnull Map<String, List<Cookie>> cookiesMap) {
|
||||||
this.cookiesMap = new ConcurrentHashMap<>(cookiesMap);
|
this();
|
||||||
|
cookiesMap.forEach((domain, cookies) ->
|
||||||
|
this.cookiesMap.put(domain, new Vector<>(cookies))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
|
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
|
||||||
cookies.forEach(cookie -> {
|
cookies.forEach(cookie -> {
|
||||||
String domain = cookie.domain();
|
String domain = cookie.domain();
|
||||||
List<Cookie> savedCookies = cookiesMap.get(domain);
|
List<Cookie> savedCookies;
|
||||||
if (savedCookies == null) {
|
synchronized (cookiesMap) {
|
||||||
savedCookies = new ArrayList<>();
|
savedCookies = cookiesMap.get(domain);
|
||||||
savedCookies.add(cookie);
|
if (savedCookies == null) {
|
||||||
cookiesMap.put(domain, savedCookies);
|
savedCookies = new Vector<>();
|
||||||
} else {
|
savedCookies.add(cookie);
|
||||||
for (Cookie savedCookie : savedCookies) {
|
cookiesMap.put(domain, savedCookies);
|
||||||
if (savedCookie.name().equals(cookie.name())) {
|
return;
|
||||||
savedCookies.remove(savedCookie);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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());
|
return getCookiesForHost(url.host());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Cookie> getCookiesForHost(String host) {
|
public List<Cookie> getCookiesForHost(@Nonnull String host) {
|
||||||
List<Cookie> cookieList = new ArrayList<>();
|
List<Cookie> cookieList = new ArrayList<>();
|
||||||
cookiesMap.forEach((domain, cookies) -> {
|
cookiesMap.forEach((domain, cookies) -> {
|
||||||
if (host.endsWith(domain)) {
|
if (host.endsWith(domain)) {
|
||||||
|
//移除过期的 cookies
|
||||||
for (int i = cookies.size() - 1; i >= 0; i--) {
|
for (int i = cookies.size() - 1; i >= 0; i--) {
|
||||||
if (cookies.get(i).expiresAt() < System.currentTimeMillis()) {
|
Cookie current = cookies.get(i);
|
||||||
cookies.remove(i);
|
if (current.expiresAt() < System.currentTimeMillis()) {
|
||||||
|
cookies.remove(current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cookieList.addAll(cookies);
|
cookieList.addAll(cookies);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.hiczp.bilibili.api.web.live;
|
package com.hiczp.bilibili.api.web.live;
|
||||||
|
|
||||||
import com.hiczp.bilibili.api.web.live.entity.SendHeartBeatResponseEntity;
|
import com.hiczp.bilibili.api.web.live.entity.SendHeartBeatResponseEntity;
|
||||||
|
import com.hiczp.bilibili.api.web.live.entity.UserInfoEntity;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.http.GET;
|
import retrofit2.http.GET;
|
||||||
import retrofit2.http.Query;
|
import retrofit2.http.Query;
|
||||||
@ -15,4 +16,14 @@ public interface LiveService {
|
|||||||
default Call<SendHeartBeatResponseEntity> sendHeartBeat() {
|
default Call<SendHeartBeatResponseEntity> sendHeartBeat() {
|
||||||
return sendHeartBeat(System.currentTimeMillis());
|
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,
|
SendBulletScreenTest.class,
|
||||||
SecurityHelperTest.class,
|
SecurityHelperTest.class,
|
||||||
AuthenticatorTest.class,
|
AuthenticatorTest.class,
|
||||||
|
WebAPITest.class,
|
||||||
LogoutTest.class
|
LogoutTest.class
|
||||||
})
|
})
|
||||||
public class RuleSuite {
|
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