mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
add CookieSpi
This commit is contained in:
parent
426d3acd9c
commit
937f36328f
@ -3,11 +3,10 @@
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 6.0.0-M17 (2024-08-30)
|
||||
# 6.0.0-M17 (2024-09-09)
|
||||
|
||||
### 计划实现
|
||||
* 【db 】 增加DDL封装
|
||||
* 【http 】 redirect跳转和Cookie
|
||||
|
||||
### ❌不兼容特性
|
||||
|
||||
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.cookie;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* Cookie SPI接口,用于自定义Cookie的实现<br>
|
||||
* 遵循RFC6265规范:https://datatracker.ietf.org/doc/html/rfc6265<br>
|
||||
* 参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies<br>
|
||||
* Cookie 主要用于以下三个方面:
|
||||
* <ul>
|
||||
* <li>会话状态管理: 用户登录状态、购物车、游戏分数或其他需要记录的信息</li>
|
||||
* <li>个性化设置: 如用户自定义设置、主题和其他设置</li>
|
||||
* <li>浏览器行为跟踪: 如跟踪分析用户行为等</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface CookieSpi {
|
||||
|
||||
/**
|
||||
* 获取Cookie名称
|
||||
*
|
||||
* @return Cookie名称
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* 获取Cookie值
|
||||
*
|
||||
* @return Cookie值
|
||||
*/
|
||||
String getValue();
|
||||
|
||||
/**
|
||||
* 限制访问 Cookie<br>
|
||||
* 标记为 Secure 的 Cookie 只应通过被 HTTPS 协议加密过的请求发送给服务端<br>
|
||||
*
|
||||
* @return 是否限制访问 Cookie
|
||||
*/
|
||||
boolean isSecure();
|
||||
|
||||
/**
|
||||
* 限制 Cookie 的作用域<br>
|
||||
* 标记为 HttpOnly 的 Cookie 只能在 HTTP 协议中访问,不能通过脚本语言(如 JavaScript)访问<br>
|
||||
*
|
||||
* @return 是否限制 Cookie 的作用域
|
||||
*/
|
||||
boolean isHttpOnly();
|
||||
|
||||
/**
|
||||
* 限制 Cookie 主机作用域,一般包含子域名<br>
|
||||
* Cookie 作用域,默认为空,表示所有域名下生效<br>
|
||||
*
|
||||
* @return Cookie 作用域
|
||||
*/
|
||||
boolean isHostOnly();
|
||||
|
||||
/**
|
||||
* 限制 Cookie 主机作用域,一般包含子域名<br>
|
||||
* Cookie 作用域,默认为空,表示所有域名下生效<br>
|
||||
*
|
||||
* @return Cookie 作用域
|
||||
*/
|
||||
String getDomain();
|
||||
|
||||
/**
|
||||
* 限制 Cookie URL路径作用域,该 URL 路径必须存在于请求的 URL 中,子路径也会匹配<br>
|
||||
* Cookie 作用域,默认为空,表示所有路径下生效<br>
|
||||
*
|
||||
* @return Cookie 作用域
|
||||
*/
|
||||
String getPath();
|
||||
|
||||
/**
|
||||
* Cookie是否过期
|
||||
*
|
||||
* @param now 当前时间,用于判断是否过期
|
||||
* @return 是否过期
|
||||
*/
|
||||
boolean isExpired(Instant now);
|
||||
|
||||
/**
|
||||
* Cookie是否过期
|
||||
*
|
||||
* @return 是否过期
|
||||
*/
|
||||
default boolean isExpired() {
|
||||
return isExpired(Instant.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义属性,用于扩展
|
||||
*
|
||||
* @param name 属性名
|
||||
* @return 属性值
|
||||
*/
|
||||
String getAttribute(String name);
|
||||
|
||||
/**
|
||||
* 是否持久化,即Cookie是否在Session关闭前一直有效
|
||||
*
|
||||
* @return 是否持久化
|
||||
*/
|
||||
boolean isPersistent();
|
||||
}
|
@ -14,20 +14,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.okhttp;
|
||||
|
||||
import okhttp3.Cookie;
|
||||
import okhttp3.HttpUrl;
|
||||
package org.dromara.hutool.http.client.cookie;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* OkHttp3 CookieStore接口
|
||||
* CookieStore接口
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface OkCookieStore {
|
||||
public interface CookieStoreSpi {
|
||||
|
||||
/**
|
||||
* 获取所有Http URI
|
||||
*
|
||||
* @return 所有Http URI
|
||||
*/
|
||||
List<URI> getURIs();
|
||||
|
||||
/**
|
||||
* 添加cookie
|
||||
@ -35,7 +40,7 @@ public interface OkCookieStore {
|
||||
* @param httpUrl HTTP url 地址
|
||||
* @param cookie cookie
|
||||
*/
|
||||
void add(HttpUrl httpUrl, Cookie cookie);
|
||||
void add(URI httpUrl, CookieSpi cookie);
|
||||
|
||||
/**
|
||||
* 添加指定 http url cookie集合
|
||||
@ -43,7 +48,11 @@ public interface OkCookieStore {
|
||||
* @param httpUrl HTTP url 地址
|
||||
* @param cookies cookie列表
|
||||
*/
|
||||
void add(HttpUrl httpUrl, List<Cookie> cookies);
|
||||
default void add(final URI httpUrl, final List<CookieSpi> cookies){
|
||||
for (final CookieSpi cookie : cookies) {
|
||||
add(httpUrl, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据HttpUrl从缓存中读取cookie集合
|
||||
@ -51,14 +60,14 @@ public interface OkCookieStore {
|
||||
* @param httpUrl HTTP url 地址
|
||||
* @return cookie集合
|
||||
*/
|
||||
List<Cookie> get(HttpUrl httpUrl);
|
||||
List<CookieSpi> get(URI httpUrl);
|
||||
|
||||
/**
|
||||
* 获取全部缓存cookie
|
||||
*
|
||||
* @return cookie集合
|
||||
*/
|
||||
List<Cookie> getCookies();
|
||||
List<CookieSpi> getCookies();
|
||||
|
||||
/**
|
||||
* 移除指定http url cookie集合
|
||||
@ -67,12 +76,12 @@ public interface OkCookieStore {
|
||||
* @param cookie cookie
|
||||
* @return 是否移除成功
|
||||
*/
|
||||
boolean remove(HttpUrl httpUrl, Cookie cookie);
|
||||
boolean remove(URI httpUrl, CookieSpi cookie);
|
||||
|
||||
/**
|
||||
* 移除所有cookie
|
||||
*
|
||||
* @return 是否移除成功
|
||||
*/
|
||||
boolean removeAll();
|
||||
boolean clear();
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.cookie;
|
||||
|
||||
import org.dromara.hutool.http.HttpException;
|
||||
import org.dromara.hutool.log.Log;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 基于内存的Cookie存储实现,线程安全
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class InMemoryCookieStore implements CookieStoreSpi {
|
||||
private static final Log LOG = Log.get();
|
||||
|
||||
private final Map<String, ConcurrentHashMap<String, CookieSpi>> cookies;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
public InMemoryCookieStore() {
|
||||
this.cookies = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<URI> getURIs() {
|
||||
final Set<String> keySet = cookies.keySet();
|
||||
final List<URI> uris = new ArrayList<>(keySet.size());
|
||||
|
||||
try {
|
||||
for (final String hostKey : keySet) {
|
||||
uris.add(new URI("http", hostKey, null, null));
|
||||
}
|
||||
} catch (final URISyntaxException e) {
|
||||
throw new HttpException(e);
|
||||
}
|
||||
return uris;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(final URI httpUrl, final CookieSpi cookie) {
|
||||
if (null == cookie || !cookie.isPersistent() || cookie.isExpired()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String hostKey = httpUrl.getHost();
|
||||
this.cookies.computeIfAbsent(hostKey, k -> new ConcurrentHashMap<>());
|
||||
|
||||
final String cookieKey = this.cookieKey(cookie);
|
||||
LOG.debug("Add cookie {}: {}", cookieKey, cookie);
|
||||
cookies.get(hostKey).put(cookieKey, cookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CookieSpi> get(final URI httpUrl) {
|
||||
final String hostKey = httpUrl.getHost();
|
||||
final List<CookieSpi> result = this.get(httpUrl.getHost());
|
||||
LOG.debug("Get cookies {}: {}", hostKey, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CookieSpi> getCookies() {
|
||||
final List<CookieSpi> result = new ArrayList<>();
|
||||
for (final String hostKey : this.cookies.keySet()) {
|
||||
result.addAll(this.get(hostKey));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(final URI httpUrl, final CookieSpi cookie) {
|
||||
return this.remove(httpUrl.getHost(), cookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clear() {
|
||||
this.cookies.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取cookie集合
|
||||
*/
|
||||
private List<CookieSpi> get(final String hostKey) {
|
||||
final List<CookieSpi> result = new ArrayList<>();
|
||||
|
||||
if (this.cookies.containsKey(hostKey)) {
|
||||
final Collection<CookieSpi> cookies = this.cookies.get(hostKey).values();
|
||||
for (final CookieSpi cookie : cookies) {
|
||||
if (cookie.isExpired()) {
|
||||
this.remove(hostKey, cookie);
|
||||
} else {
|
||||
result.add(cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中移除cookie
|
||||
*
|
||||
* @param hostKey hostKey
|
||||
* @param cookie cookie
|
||||
*/
|
||||
private boolean remove(final String hostKey, final CookieSpi cookie) {
|
||||
final String cookieKey = this.cookieKey(cookie);
|
||||
if (this.cookies.containsKey(hostKey) && this.cookies.get(hostKey).containsKey(cookieKey)) {
|
||||
// 从内存中移除httpUrl对应的cookie
|
||||
this.cookies.get(hostKey).remove(cookieKey);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取cookie的key<br>
|
||||
* 格式:name + domain
|
||||
*
|
||||
* @param cookie cookie
|
||||
* @return cookie的key
|
||||
*/
|
||||
private String cookieKey(final CookieSpi cookie) {
|
||||
return cookie == null ? null : cookie.getName() + cookie.getDomain();
|
||||
}
|
||||
}
|
@ -16,9 +16,6 @@
|
||||
|
||||
package org.dromara.hutool.http.client.cookie;
|
||||
|
||||
import java.net.CookieManager;
|
||||
import java.net.CookieStore;
|
||||
import java.net.HttpCookie;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
@ -28,15 +25,15 @@ import java.util.List;
|
||||
* 见:https://stackoverflow.com/questions/16305486/cookiemanager-for-multiple-threads
|
||||
*
|
||||
* @author looly
|
||||
* @since 4.1.18
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class ThreadLocalCookieStore implements CookieStore {
|
||||
public class ThreadLocalCookieStore implements CookieStoreSpi {
|
||||
|
||||
private final static ThreadLocal<CookieStore> STORES = new ThreadLocal<CookieStore>() {
|
||||
private final static ThreadLocal<CookieStoreSpi> STORES = new ThreadLocal<CookieStoreSpi>() {
|
||||
@Override
|
||||
protected synchronized CookieStore initialValue() {
|
||||
protected synchronized CookieStoreSpi initialValue() {
|
||||
/* InMemoryCookieStore */
|
||||
return (new CookieManager()).getCookieStore();
|
||||
return new InMemoryCookieStore();
|
||||
}
|
||||
};
|
||||
|
||||
@ -45,7 +42,7 @@ public class ThreadLocalCookieStore implements CookieStore {
|
||||
*
|
||||
* @return CookieStore
|
||||
*/
|
||||
public CookieStore getCookieStore() {
|
||||
public CookieStoreSpi getCookieStore() {
|
||||
return STORES.get();
|
||||
}
|
||||
|
||||
@ -59,33 +56,33 @@ public class ThreadLocalCookieStore implements CookieStore {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(final URI uri, final HttpCookie cookie) {
|
||||
getCookieStore().add(uri, cookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpCookie> get(final URI uri) {
|
||||
return getCookieStore().get(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpCookie> getCookies() {
|
||||
return getCookieStore().getCookies();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<URI> getURIs() {
|
||||
return getCookieStore().getURIs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(final URI uri, final HttpCookie cookie) {
|
||||
return getCookieStore().remove(uri, cookie);
|
||||
public void add(final URI httpUrl, final CookieSpi cookie) {
|
||||
getCookieStore().add(httpUrl, cookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll() {
|
||||
return getCookieStore().removeAll();
|
||||
public List<CookieSpi> get(final URI httpUrl) {
|
||||
return getCookieStore().get(httpUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CookieSpi> getCookies() {
|
||||
return getCookieStore().getCookies();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(final URI httpUrl, final CookieSpi cookie) {
|
||||
return getCookieStore().remove(httpUrl, cookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clear() {
|
||||
return getCookieStore().clear();
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.dromara.hutool.http.client.engine;
|
||||
|
||||
import org.dromara.hutool.http.client.ClientConfig;
|
||||
import org.dromara.hutool.http.client.cookie.CookieStoreSpi;
|
||||
|
||||
/**
|
||||
* 客户端引擎抽象类,用于保存配置和定义初始化,并提供:
|
||||
@ -31,6 +32,16 @@ import org.dromara.hutool.http.client.ClientConfig;
|
||||
public abstract class AbstractClientEngine implements ClientEngine{
|
||||
|
||||
protected ClientConfig config;
|
||||
protected CookieStoreSpi cookieStore;
|
||||
|
||||
/**
|
||||
* 获得Cookie存储器
|
||||
*
|
||||
* @return Cookie存储器
|
||||
*/
|
||||
public CookieStoreSpi getCookieStore() {
|
||||
return this.cookieStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientEngine init(final ClientConfig config) {
|
||||
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.httpclient4;
|
||||
|
||||
import org.apache.http.cookie.Cookie;
|
||||
import org.dromara.hutool.core.date.DateUtil;
|
||||
import org.dromara.hutool.core.lang.wrapper.SimpleWrapper;
|
||||
import org.dromara.hutool.http.client.cookie.CookieSpi;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* HttpClient4 Cookie实现
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class HttpClient4Cookie extends SimpleWrapper<Cookie> implements CookieSpi {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param raw 原始对象
|
||||
*/
|
||||
public HttpClient4Cookie(final Cookie raw) {
|
||||
super(raw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return raw.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return raw.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return raw.isSecure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHttpOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHostOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDomain() {
|
||||
return raw.getDomain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return raw.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired(final Instant now) {
|
||||
return raw.isExpired(DateUtil.date(now));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttribute(final String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return raw.isPersistent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return raw.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.httpclient4;
|
||||
|
||||
import org.apache.http.client.CookieStore;
|
||||
import org.apache.http.cookie.Cookie;
|
||||
import org.dromara.hutool.core.lang.wrapper.SimpleWrapper;
|
||||
import org.dromara.hutool.http.HttpException;
|
||||
import org.dromara.hutool.http.client.cookie.CookieSpi;
|
||||
import org.dromara.hutool.http.client.cookie.CookieStoreSpi;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Apache HttpClient4的Cookie存储器实现
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class HttpClient4CookieStore extends SimpleWrapper<CookieStoreSpi> implements CookieStore {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param raw Cookie存储器
|
||||
*/
|
||||
public HttpClient4CookieStore(final CookieStoreSpi raw) {
|
||||
super(raw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCookie(final Cookie cookie) {
|
||||
final URI uri;
|
||||
try {
|
||||
uri = new URI("http", cookie.getDomain(), cookie.getPath(), null);
|
||||
} catch (final URISyntaxException e) {
|
||||
throw new HttpException(e);
|
||||
}
|
||||
|
||||
this.raw.add(uri, new HttpClient4Cookie(cookie));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cookie> getCookies() {
|
||||
final List<CookieSpi> cookies = this.raw.getCookies();
|
||||
final List<Cookie> result = new ArrayList<>(cookies.size());
|
||||
for (final CookieSpi cookie : cookies) {
|
||||
result.add(((HttpClient4Cookie) cookie).getRaw());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearExpired(final Date date) {
|
||||
// get时检查过期
|
||||
this.raw.getCookies();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.raw.clear();
|
||||
}
|
||||
}
|
@ -20,7 +20,6 @@ import org.apache.http.Header;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.CookieStore;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.methods.RequestBuilder;
|
||||
@ -34,11 +33,12 @@ import org.dromara.hutool.core.net.url.UrlBuilder;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.http.GlobalHeaders;
|
||||
import org.dromara.hutool.http.HttpException;
|
||||
import org.dromara.hutool.http.client.ClientConfig;
|
||||
import org.dromara.hutool.http.client.ApacheHttpClientConfig;
|
||||
import org.dromara.hutool.http.client.ClientConfig;
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
import org.dromara.hutool.http.client.Response;
|
||||
import org.dromara.hutool.http.client.body.HttpBody;
|
||||
import org.dromara.hutool.http.client.cookie.InMemoryCookieStore;
|
||||
import org.dromara.hutool.http.client.engine.AbstractClientEngine;
|
||||
import org.dromara.hutool.http.meta.HeaderName;
|
||||
import org.dromara.hutool.http.proxy.HttpProxy;
|
||||
@ -60,7 +60,6 @@ import java.util.Map;
|
||||
public class HttpClient4Engine extends AbstractClientEngine {
|
||||
|
||||
private CloseableHttpClient engine;
|
||||
private CookieStore cookieStore;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
@ -71,15 +70,6 @@ public class HttpClient4Engine extends AbstractClientEngine {
|
||||
Assert.notNull(CloseableHttpClient.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得Cookie存储器
|
||||
*
|
||||
* @return Cookie存储器
|
||||
*/
|
||||
public CookieStore getCookieStore() {
|
||||
return this.cookieStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response send(final Request message) {
|
||||
initEngine();
|
||||
@ -150,8 +140,8 @@ public class HttpClient4Engine extends AbstractClientEngine {
|
||||
|
||||
// Cookie管理
|
||||
if(config.isUseCookieManager()){
|
||||
this.cookieStore = new BasicCookieStore();
|
||||
clientBuilder.setDefaultCookieStore(this.cookieStore);
|
||||
this.cookieStore = new InMemoryCookieStore();
|
||||
clientBuilder.setDefaultCookieStore(new HttpClient4CookieStore(this.cookieStore));
|
||||
}
|
||||
|
||||
this.engine = clientBuilder.build();
|
||||
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.httpclient5;
|
||||
|
||||
import org.apache.hc.client5.http.cookie.Cookie;
|
||||
import org.dromara.hutool.core.lang.wrapper.SimpleWrapper;
|
||||
import org.dromara.hutool.http.client.cookie.CookieSpi;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* HttpClient5 Cookie实现
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class HttpClient5Cookie extends SimpleWrapper<Cookie> implements CookieSpi {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param raw 原始对象
|
||||
*/
|
||||
public HttpClient5Cookie(final Cookie raw) {
|
||||
super(raw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return raw.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return raw.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return raw.isSecure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHttpOnly() {
|
||||
return raw.isHttpOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHostOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDomain() {
|
||||
return raw.getDomain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return raw.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired(final Instant now) {
|
||||
return raw.isExpired(now);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttribute(final String name) {
|
||||
return raw.getAttribute(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return raw.isPersistent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return raw.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.httpclient5;
|
||||
|
||||
import org.apache.hc.client5.http.cookie.Cookie;
|
||||
import org.apache.hc.client5.http.cookie.CookieStore;
|
||||
import org.dromara.hutool.core.lang.wrapper.SimpleWrapper;
|
||||
import org.dromara.hutool.http.HttpException;
|
||||
import org.dromara.hutool.http.client.cookie.CookieSpi;
|
||||
import org.dromara.hutool.http.client.cookie.CookieStoreSpi;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* HttpClient5 Cookie存储器实现
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class HttpClient5CookieStore extends SimpleWrapper<CookieStoreSpi> implements CookieStore {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param cookieStore Cookie存储器
|
||||
*/
|
||||
public HttpClient5CookieStore(final CookieStoreSpi cookieStore) {
|
||||
super(cookieStore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCookie(final Cookie cookie) {
|
||||
final URI uri;
|
||||
try {
|
||||
uri = new URI("http", cookie.getDomain(), cookie.getPath(), null);
|
||||
} catch (final URISyntaxException e) {
|
||||
throw new HttpException(e);
|
||||
}
|
||||
|
||||
this.raw.add(uri, new HttpClient5Cookie(cookie));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cookie> getCookies() {
|
||||
final List<CookieSpi> cookies = this.raw.getCookies();
|
||||
final List<Cookie> result = new ArrayList<>(cookies.size());
|
||||
for (final CookieSpi cookie : cookies) {
|
||||
result.add(((HttpClient5Cookie) cookie).getRaw());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearExpired(final Date date) {
|
||||
// get时检查过期
|
||||
this.raw.getCookies();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.raw.clear();
|
||||
}
|
||||
}
|
@ -21,8 +21,6 @@ import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
|
||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
||||
import org.apache.hc.client5.http.cookie.CookieStore;
|
||||
import org.apache.hc.client5.http.impl.DefaultRedirectStrategy;
|
||||
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
|
||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||
@ -41,11 +39,12 @@ import org.dromara.hutool.core.net.url.UrlBuilder;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.http.GlobalHeaders;
|
||||
import org.dromara.hutool.http.HttpException;
|
||||
import org.dromara.hutool.http.client.ClientConfig;
|
||||
import org.dromara.hutool.http.client.ApacheHttpClientConfig;
|
||||
import org.dromara.hutool.http.client.ClientConfig;
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
import org.dromara.hutool.http.client.Response;
|
||||
import org.dromara.hutool.http.client.body.HttpBody;
|
||||
import org.dromara.hutool.http.client.cookie.InMemoryCookieStore;
|
||||
import org.dromara.hutool.http.client.engine.AbstractClientEngine;
|
||||
import org.dromara.hutool.http.meta.HeaderName;
|
||||
import org.dromara.hutool.http.proxy.HttpProxy;
|
||||
@ -68,7 +67,6 @@ import java.util.concurrent.TimeUnit;
|
||||
public class HttpClient5Engine extends AbstractClientEngine {
|
||||
|
||||
private CloseableHttpClient engine;
|
||||
private CookieStore cookieStore;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
@ -79,15 +77,6 @@ public class HttpClient5Engine extends AbstractClientEngine {
|
||||
Assert.notNull(CloseableHttpClient.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得Cookie存储器
|
||||
*
|
||||
* @return Cookie存储器
|
||||
*/
|
||||
public CookieStore getCookieStore() {
|
||||
return this.cookieStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response send(final Request message) {
|
||||
initEngine();
|
||||
@ -152,8 +141,8 @@ public class HttpClient5Engine extends AbstractClientEngine {
|
||||
|
||||
// Cookie管理
|
||||
if(config.isUseCookieManager()){
|
||||
this.cookieStore = new BasicCookieStore();
|
||||
clientBuilder.setDefaultCookieStore(this.cookieStore);
|
||||
this.cookieStore = new InMemoryCookieStore();
|
||||
clientBuilder.setDefaultCookieStore(new HttpClient5CookieStore(this.cookieStore));
|
||||
}
|
||||
|
||||
this.engine = clientBuilder.build();
|
||||
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.jdk;
|
||||
|
||||
import org.dromara.hutool.core.lang.wrapper.SimpleWrapper;
|
||||
import org.dromara.hutool.core.reflect.method.MethodUtil;
|
||||
import org.dromara.hutool.http.client.cookie.CookieSpi;
|
||||
|
||||
import java.net.HttpCookie;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* JDK Cookie实现
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class JdkCookie extends SimpleWrapper<HttpCookie> implements CookieSpi {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param httpCookie 原始对象
|
||||
*/
|
||||
public JdkCookie(final HttpCookie httpCookie) {
|
||||
super(httpCookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return raw.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return raw.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return raw.getSecure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHttpOnly() {
|
||||
return raw.isHttpOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHostOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDomain() {
|
||||
return raw.getDomain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return raw.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired() {
|
||||
return raw.hasExpired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired(final Instant now) {
|
||||
final long maxAge = raw.getMaxAge();
|
||||
if (maxAge == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (maxAge < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final long creationTime = MethodUtil.invoke(raw, "getCreationTime");
|
||||
final long deltaSecond = (now.toEpochMilli() - creationTime) / 1000;
|
||||
return deltaSecond > maxAge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttribute(final String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ package org.dromara.hutool.http.client.engine.jdk;
|
||||
import org.dromara.hutool.core.io.IORuntimeException;
|
||||
import org.dromara.hutool.core.map.MapUtil;
|
||||
import org.dromara.hutool.core.net.url.UrlUtil;
|
||||
import org.dromara.hutool.http.client.cookie.ThreadLocalCookieStore;
|
||||
import org.dromara.hutool.http.client.cookie.InMemoryCookieStore;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
@ -50,7 +50,7 @@ public class JdkCookieManager implements Closeable {
|
||||
* 构造
|
||||
*/
|
||||
public JdkCookieManager() {
|
||||
this(new CookieManager(new ThreadLocalCookieStore(), CookiePolicy.ACCEPT_ALL));
|
||||
this(new CookieManager(new JdkCookieStore(new InMemoryCookieStore()), CookiePolicy.ACCEPT_ALL));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.jdk;
|
||||
|
||||
import org.dromara.hutool.core.lang.wrapper.SimpleWrapper;
|
||||
import org.dromara.hutool.http.client.cookie.CookieSpi;
|
||||
import org.dromara.hutool.http.client.cookie.CookieStoreSpi;
|
||||
|
||||
import java.net.CookieStore;
|
||||
import java.net.HttpCookie;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* JDK CookieStore实现
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class JdkCookieStore extends SimpleWrapper<CookieStoreSpi> implements CookieStore {
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param raw 原始对象
|
||||
*/
|
||||
public JdkCookieStore(final CookieStoreSpi raw) {
|
||||
super(raw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(final URI uri, final HttpCookie cookie) {
|
||||
this.raw.add(uri, new JdkCookie(cookie));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpCookie> get(final URI uri) {
|
||||
final List<CookieSpi> cookieSpis = this.raw.get(uri);
|
||||
if (null == cookieSpis) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<HttpCookie> result = new ArrayList<>(cookieSpis.size());
|
||||
for (final CookieSpi cookieSpi : cookieSpis) {
|
||||
result.add(((JdkCookie) cookieSpi).getRaw());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpCookie> getCookies() {
|
||||
final List<CookieSpi> cookieSpis = this.raw.getCookies();
|
||||
if (null == cookieSpis) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<HttpCookie> result = new ArrayList<>(cookieSpis.size());
|
||||
for (final CookieSpi cookieSpi : cookieSpis) {
|
||||
result.add(((JdkCookie) cookieSpi).getRaw());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<URI> getURIs() {
|
||||
return this.raw.getURIs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(final URI uri, final HttpCookie cookie) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -19,7 +19,11 @@ package org.dromara.hutool.http.client.engine.okhttp;
|
||||
import okhttp3.Cookie;
|
||||
import okhttp3.CookieJar;
|
||||
import okhttp3.HttpUrl;
|
||||
import org.dromara.hutool.core.collection.CollUtil;
|
||||
import org.dromara.hutool.http.client.cookie.CookieSpi;
|
||||
import org.dromara.hutool.http.client.cookie.CookieStoreSpi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -30,13 +34,15 @@ import java.util.List;
|
||||
*/
|
||||
public class CookieJarImpl implements CookieJar {
|
||||
|
||||
private final OkCookieStore cookieStore;
|
||||
private final CookieStoreSpi cookieStore;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param cookieStore Cookie存储器,用于自定义Cookie存储实现
|
||||
*/
|
||||
public CookieJarImpl() {
|
||||
this(new InMemoryOkCookieStore());
|
||||
public CookieJarImpl(final CookieStoreSpi cookieStore) {
|
||||
this.cookieStore = cookieStore;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,26 +50,28 @@ public class CookieJarImpl implements CookieJar {
|
||||
*
|
||||
* @return Cookie存储器
|
||||
*/
|
||||
public OkCookieStore getCookieStore() {
|
||||
public CookieStoreSpi getCookieStore() {
|
||||
return this.cookieStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param cookieStore Cookie存储器,用于自定义Cookie存储实现
|
||||
*/
|
||||
public CookieJarImpl(final OkCookieStore cookieStore) {
|
||||
this.cookieStore = cookieStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cookie> loadForRequest(final HttpUrl httpUrl) {
|
||||
return this.cookieStore.get(httpUrl);
|
||||
final List<CookieSpi> cookieSpis = this.cookieStore.get(httpUrl.uri());
|
||||
final List<Cookie> cookies = new ArrayList<>(cookieSpis.size());
|
||||
for (final CookieSpi cookieSpi : cookieSpis) {
|
||||
cookies.add(((OkCookie)cookieSpi).getRaw());
|
||||
}
|
||||
return cookies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveFromResponse(final HttpUrl httpUrl, final List<Cookie> list) {
|
||||
this.cookieStore.add(httpUrl, list);
|
||||
if(CollUtil.isEmpty(list)){
|
||||
return;
|
||||
}
|
||||
|
||||
for (final Cookie cookie : list) {
|
||||
this.cookieStore.add(httpUrl.uri(), new OkCookie(cookie));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.okhttp;
|
||||
|
||||
import okhttp3.Cookie;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 内存CookieStore实现,用于OkHttp3
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class InMemoryOkCookieStore implements OkCookieStore {
|
||||
|
||||
private final HashMap<String, ConcurrentHashMap<String, Cookie>> cookies;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
public InMemoryOkCookieStore() {
|
||||
this.cookies = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(final HttpUrl httpUrl, final Cookie cookie) {
|
||||
if (!cookie.persistent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String name = this.cookieName(cookie);
|
||||
final String hostKey = httpUrl.host();
|
||||
|
||||
if (!this.cookies.containsKey(hostKey)) {
|
||||
this.cookies.put(hostKey, new ConcurrentHashMap<>());
|
||||
}
|
||||
cookies.get(hostKey).put(name, cookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(final HttpUrl httpUrl, final List<Cookie> cookies) {
|
||||
for (final Cookie cookie : cookies) {
|
||||
if (isCookieExpired(cookie)) {
|
||||
continue;
|
||||
}
|
||||
this.add(httpUrl, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cookie> get(final HttpUrl httpUrl) {
|
||||
return this.get(httpUrl.host());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cookie> getCookies() {
|
||||
final ArrayList<Cookie> result = new ArrayList<>();
|
||||
|
||||
for (final String hostKey : this.cookies.keySet()) {
|
||||
result.addAll(this.get(hostKey));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取cookie集合
|
||||
*/
|
||||
private List<Cookie> get(final String hostKey) {
|
||||
final ArrayList<Cookie> result = new ArrayList<>();
|
||||
|
||||
if (this.cookies.containsKey(hostKey)) {
|
||||
final Collection<Cookie> cookies = this.cookies.get(hostKey).values();
|
||||
for (final Cookie cookie : cookies) {
|
||||
if (isCookieExpired(cookie)) {
|
||||
this.remove(hostKey, cookie);
|
||||
} else {
|
||||
result.add(cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(final HttpUrl httpUrl, final Cookie cookie) {
|
||||
return this.remove(httpUrl.host(), cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中移除cookie
|
||||
*
|
||||
* @param hostKey hostKey
|
||||
* @param cookie cookie
|
||||
*/
|
||||
private boolean remove(final String hostKey, final Cookie cookie) {
|
||||
final String name = this.cookieName(cookie);
|
||||
if (this.cookies.containsKey(hostKey) && this.cookies.get(hostKey).containsKey(name)) {
|
||||
// 从内存中移除httpUrl对应的cookie
|
||||
this.cookies.get(hostKey).remove(name);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll() {
|
||||
this.cookies.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断cookie是否失效
|
||||
*/
|
||||
private boolean isCookieExpired(final Cookie cookie) {
|
||||
return cookie.expiresAt() < System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取cookie的key<br>
|
||||
* 格式:name + domain
|
||||
*
|
||||
* @param cookie cookie
|
||||
* @return cookie的key
|
||||
*/
|
||||
private String cookieName(final Cookie cookie) {
|
||||
return cookie == null ? null : cookie.name() + cookie.domain();
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.okhttp;
|
||||
|
||||
import okhttp3.Cookie;
|
||||
import org.dromara.hutool.core.lang.wrapper.SimpleWrapper;
|
||||
import org.dromara.hutool.http.client.cookie.CookieSpi;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* OkHttp Cookie实现
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class OkCookie extends SimpleWrapper<Cookie> implements CookieSpi {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param raw 原始对象
|
||||
*/
|
||||
public OkCookie(final Cookie raw) {
|
||||
super(raw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return raw.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return raw.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return raw.secure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHttpOnly() {
|
||||
return raw.httpOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHostOnly() {
|
||||
return raw.hostOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDomain() {
|
||||
return raw.domain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return raw.path();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired(final Instant now) {
|
||||
return raw.expiresAt() < now.toEpochMilli();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttribute(final String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return raw.persistent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return raw.toString();
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ import org.dromara.hutool.http.client.ClientConfig;
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
import org.dromara.hutool.http.client.Response;
|
||||
import org.dromara.hutool.http.client.body.HttpBody;
|
||||
import org.dromara.hutool.http.client.cookie.InMemoryCookieStore;
|
||||
import org.dromara.hutool.http.client.engine.AbstractClientEngine;
|
||||
import org.dromara.hutool.http.proxy.HttpProxy;
|
||||
import org.dromara.hutool.http.ssl.SSLInfo;
|
||||
@ -43,7 +44,6 @@ import java.util.concurrent.TimeUnit;
|
||||
public class OkHttpEngine extends AbstractClientEngine {
|
||||
|
||||
private OkHttpClient client;
|
||||
private OkCookieStore cookieStore;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
@ -54,15 +54,6 @@ public class OkHttpEngine extends AbstractClientEngine {
|
||||
Assert.notNull(OkHttpClient.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得Cookie存储器
|
||||
*
|
||||
* @return Cookie存储器
|
||||
*/
|
||||
public OkCookieStore getCookieStore() {
|
||||
return this.cookieStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OkHttpEngine init(final ClientConfig config) {
|
||||
this.config = config;
|
||||
@ -145,7 +136,7 @@ public class OkHttpEngine extends AbstractClientEngine {
|
||||
|
||||
// Cookie管理
|
||||
if (this.config.isUseCookieManager()) {
|
||||
this.cookieStore = new InMemoryOkCookieStore();
|
||||
this.cookieStore = new InMemoryCookieStore();
|
||||
builder.cookieJar(new CookieJarImpl(this.cookieStore));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user