您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
在 Java 中,可以使用 HttpURLConnection 类或者第三方库如 Apache HttpClient 或者 OkHttp 来实现 HTTP 缓存
import java.io.*;
import java.net.*;
import java.util.*;
public class HttpCache {
private static final int MAX_CACHE_SIZE = 10 * 1024 * 1024; // 10 MiB
private Map<String, CacheEntry> cache = new LinkedHashMap<String, CacheEntry>(MAX_CACHE_SIZE, 0.75f, true) {
protected boolean removeEldestEntry(Map.Entry<String, CacheEntry> eldest) {
return size() > MAX_CACHE_SIZE;
}
};
public InputStream get(String url) throws IOException {
CacheEntry entry = cache.get(url);
if (entry == null || entry.isExpired()) {
URLConnection connection = new URL(url).openConnection();
connection.setUseCaches(true);
connection.connect();
if (entry == null) {
entry = new CacheEntry();
} else {
entry.revalidate(connection.getExpiration());
}
entry.setContentLength((int) connection.getContentLength());
entry.setContentType(connection.getContentType());
entry.setLastModified(connection.getLastModified());
cache.put(url, entry);
}
return new BufferedInputStream(new FileInputStream(entry.getFile()));
}
private static class CacheEntry implements Serializable {
private File file;
private long lastModified;
private int contentLength;
private String contentType;
private transient long expiration;
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public long getLastModified() {
return lastModified;
}
public void setLastModified(long lastModified) {
this.lastModified = lastModified;
}
public int getContentLength() {
return contentLength;
}
public void setContentLength(int contentLength) {
this.contentLength = contentLength;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public long getExpiration() {
return expiration;
}
public void revalidate(long currentTime) {
this.expiration = currentTime + (3600 * 1000); // 1 hour
}
}
}
首先,需要添加 Apache HttpClient 依赖到项目中。如果使用 Maven,可以在 pom.xml 文件中添加以下依赖:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
然后,可以使用以下代码实现 HTTP 缓存:
import org.apache.http.*;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.cache.CacheConfig;
import org.apache.http.impl.client.cache.CachingHttpClientConnectionManager;
import java.io.*;
public class HttpCache {
private static final int MAX_CACHE_SIZE = 10 * 1024 * 1024; // 10 MiB
public InputStream get(String url) throws IOException {
CloseableHttpClient httpClient = createHttpClientWithCache();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse httpResponse = httpClient.execute(httpGet);
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
Header[] headers = httpResponse.getHeaders("Last-Modified");
long lastModified = -1;
if (headers != null && headers.length > 0) {
lastModified = Long.parseLong(headers[0].getValue());
}
File cacheFile = new File(getCacheDirectory(), url.hashCode() + ".dat");
if (lastModified != -1 && isCacheValid(lastModified, cacheFile)) {
return new BufferedInputStream(new FileInputStream(cacheFile));
}
HttpEntity httpEntity = httpResponse.getEntity();
if (httpEntity != null) {
File outputFile = new File(getCacheDirectory(), url.hashCode() + ".dat");
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = httpEntity.getContent().read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
return new BufferedInputStream(new FileInputStream(outputFile));
}
}
} finally {
httpClient.close();
}
throw new IOException("Failed to fetch URL: " + url);
}
private CloseableHttpClient createHttpClientWithCache() {
CachingHttpClientConnectionManager cmcm = new CachingHttpClientConnectionManager();
cmcm.setMaxTotal(200);
cmcm.setDefaultMaxPerRoute(20);
CacheConfig cc = new CacheConfig();
cc.setMaxSize(MAX_CACHE_SIZE);
cc.setExpireAfterWrite(3600); // 1 hour
cc.setMaxSizePolicy(CacheConfig.MaxSizePolicy.MAX_SIZE_PER_ROUTE);
return HttpClients.custom()
.setConnectionManager(cmcm)
.setCacheConfig(cc)
.build();
}
private boolean isCacheValid(long lastModified, File cacheFile) {
return lastModified == cacheFile.lastModified() && !cacheFile.exists() || System.currentTimeMillis() < cacheFile.lastModified() + (3600 * 1000); // 1 hour
}
private File getCacheDirectory() {
File cacheDir = new File(System.getProperty("java.io.tmpdir"), "http-cache");
if (!cacheDir.exists()) {
cacheDir.mkdirs();
}
return cacheDir;
}
}
首先,需要添加 OkHttp 依赖到项目中。如果使用 Maven,可以在 pom.xml 文件中添加以下依赖:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.1</version>
</dependency>
然后,可以使用以下代码实现 HTTP 缓存:
import okhttp3.*;
import java.io.*;
import java.util.concurrent.TimeUnit;
public class HttpCache {
private static final int MAX_CACHE_SIZE = 10 * 1024 * 1024; // 10 MiB
private Cache cache;
public HttpCache() throws IOException {
File cacheDirectory = new File(System.getProperty("java.io.tmpdir"), "http-cache");
cache = new Cache(cacheDirectory, MAX_CACHE_SIZE);
}
public InputStream get(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.cacheControl(CacheControl.FORCE_CACHE)
.build();
try (Response response = client().newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
long currentTime = System.currentTimeMillis();
long expiration = response.header("Last-Modified") != null ? Long.parseLong(response.header("Last-Modified")) : currentTime + (3600 * 1000); // 1 hour
File cacheFile = new File(cache.directory(), url.hashCode() + ".dat");
if (isCacheValid(currentTime, expiration, cacheFile)) {
return new BufferedInputStream(new FileInputStream(cacheFile));
}
ResponseBody responseBody = response.body();
if (responseBody != null) {
File outputFile = new File(cache.directory(), url.hashCode() + ".dat");
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = responseBody.bytes().read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
}
}
throw new IOException("Failed to fetch URL: " + url);
}
private boolean isCacheValid(long currentTime, long expiration, File cacheFile) {
return currentTime < expiration && lastModified(cacheFile) == currentTime;
}
private long lastModified(File cacheFile) {
try {
return cacheFile.lastModified();
} catch (Exception e) {
return -1;
}
}
private OkHttpClient client() {
return new OkHttpClient.Builder()
.cache(cache)
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
}
}
这些示例代码展示了如何在 Java 中实现 HTTP 缓存。你可以根据自己的需求进行调整和优化。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。