java网络编程之缓存(二)介绍了javaWeb缓存的三个接口类。
下边我会给出这三个接口类的memory实现,然后通过注册系统级uc缓存使用我们自己定义的缓存。
MemoryCacheRequest
MemoryCacheResponse
MemoryResponseCache
这三个类分别实现了CacheRequest,CacheResponse,ResponseCache接口,MemoryCacheRequest通过定义一个简单的字节输出流来缓存对应的缓存信息。
MemoryCacheResponse可以获得对应MemoryCacheRequest的内容输入流从而获得输入。MemoryResponseCache提供了request和response的映射、对应
关系和一定的“缓存与否”校验。
另外这个程序也用到了java网络编程之缓存(一)中定义的CacheControl来解析连接对应的Cache-control首部。
package com.z;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.net.CacheRequest;
public class MemoryCacheRequest extends CacheRequest {
ByteArrayOutputStream out = new ByteArrayOutputStream();
@Override
public void abort() {
out.reset();
}
@Override
public OutputStream getBody() throws IOException {
return out;
}
public byte[] getData(){
if(out.size() == 0) return null;
else return out.toByteArray();
}
}
package com.z;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.CacheResponse;
import java.net.URLConnection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class MemoryCacheResponse extends CacheResponse{
private MemoryCacheRequest request;
private Map<String, List<String>> headers;
private CacheControl control;
private Date expires;
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream(request.getData());
}
@Override
public Map<String, List<String>> getHeaders() throws IOException {
return headers;
}
public MemoryCacheResponse(MemoryCacheRequest request, URLConnection uc,CacheControl control){
this.request = request;
this.headers = Collections.unmodifiableMap(uc.getHeaderFields());
this.control = control;
this.expires = new Date(uc.getExpiration());
}
public CacheControl getControl(){
return control;
}
public boolean isExpired(){
Date now = new Date();
if(this.control.maxAge().before(now)) return true;
else if(expires != null && control.maxAge() != null){
return expires.before(now);
}
return false;
}
}
package com.z;
import java.io.IOException;
import java.net.CacheRequest;
import java.net.CacheResponse;
import java.net.ResponseCache;
import java.net.URI;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MemoryResponseCache extends ResponseCache{
private int maxEntries;
private final Map<URI,MemoryCacheResponse> responses = new ConcurrentHashMap<URI,MemoryCacheResponse>();
public MemoryResponseCache(int maxEntries){
this.maxEntries = maxEntries;
}
@Override
public CacheResponse get(URI uri, String requestMethod,
Map<String, List<String>> requestHeaders) throws IOException {
if("GET".equals(requestMethod)){
MemoryCacheResponse response = responses.get(uri);
if(response != null && response.isExpired()){
responses.remove(response);
response = null;
}
return response;
}
return null;
}
@Override
public CacheRequest put(URI uri, URLConnection conn) throws IOException {
if(responses.size() >= maxEntries)
return null;
CacheControl control = new CacheControl(conn.getHeaderField("Cache-control"));
if(control.noStore()){
return null;
}else if(!conn.getHeaderField(0).startsWith("GET")){//只缓存get请求
return null;
}
MemoryCacheRequest request = new MemoryCacheRequest();
MemoryCacheResponse response = new MemoryCacheResponse(request,conn,control);
responses.put(uri, response);
return request;
}
}
通过以上的定义,我们就可以使用java关于URLconnection的系统级缓存。