All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.ymate.platform.webmvc.util.WebCacheHelper Maven / Gradle / Ivy
/*
* Copyright 2007-2017 the original author or authors.
*
* 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 net.ymate.platform.webmvc.util;
import net.ymate.platform.cache.ICaches;
import net.ymate.platform.core.lang.PairObject;
import net.ymate.platform.core.util.DateTimeUtils;
import net.ymate.platform.webmvc.PageMeta;
import net.ymate.platform.webmvc.base.Type;
import org.apache.commons.lang.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author 刘镇 ([email protected] ) on 16/3/28 下午7:56
* @version 1.0
*/
public class WebCacheHelper {
private static final int EMPTY_GZIPPED_CONTENT_SIZE = 20;
private HttpServletRequest __request;
private HttpServletResponse __response;
private PageMeta __element;
private ICaches.Scope __scope;
private WebCacheHelper(HttpServletRequest request, HttpServletResponse response, PageMeta pageMeta, ICaches.Scope scope) {
__request = request;
__response = response;
__element = pageMeta;
__scope = scope;
//
if (ICaches.Scope.DEFAULT.equals(__scope)) {
for (final Iterator>> _headerIt = __element.getHeaders().entrySet().iterator(); _headerIt.hasNext(); ) {
final Map.Entry> _header = _headerIt.next();
if ("Last-Modified".equalsIgnoreCase(_header.getKey()) ||
"Expires".equalsIgnoreCase(_header.getKey()) ||
"Cache-Control".equalsIgnoreCase(_header.getKey()) ||
"ETag".equalsIgnoreCase(_header.getKey())) {
_headerIt.remove();
}
}
long _lastModified = __element.getLastUpdateTime();
_lastModified = TimeUnit.MILLISECONDS.toSeconds(_lastModified);
_lastModified = TimeUnit.SECONDS.toMillis(_lastModified);
//
long _expiresTime = System.currentTimeMillis() + __element.getTimeout();
//
__element.getHeaders().put("Last-Modified", new PairObject(Type.HeaderType.DATE, _lastModified));
__element.getHeaders().put("Expires", new PairObject(Type.HeaderType.DATE, _expiresTime));
__element.getHeaders().put("Cache-Control", new PairObject(Type.HeaderType.STRING, "max-age=" + __element.getTimeout()));
__element.getHeaders().put("ETag", new PairObject(Type.HeaderType.STRING, __doGenerateEtag(__element.getTimeout())));
}
}
private String __doGenerateEtag(long ttlMilliseconds) {
StringBuilder stringBuffer = new StringBuilder();
Long eTagRaw = System.currentTimeMillis() + ttlMilliseconds;
return stringBuffer.append("\"").append(eTagRaw).append("\"").toString();
}
public static WebCacheHelper bind(HttpServletRequest request, HttpServletResponse response, PageMeta pageMeta, ICaches.Scope scope) {
return new WebCacheHelper(request, response, pageMeta, scope);
}
public void writeResponse() throws Exception {
if (ICaches.Scope.DEFAULT.equals(__scope)) {
for (final Map.Entry> _header : __element.getHeaders().entrySet()) {
if ("ETag".equals(_header.getKey())) {
String _ifNoneMatch = __request.getHeader("If-None-Match");
if (_header.getValue() != null && _header.getValue().getValue().equals(_ifNoneMatch)) {
__response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
break;
}
if (_header.getValue().getValue() != null && "Last-Modified".equals(_header.getKey())) {
long _ifModifiedSince = __request.getDateHeader("If-Modified-Since");
if (_ifModifiedSince != -1) {
final Date _requestDate = new Date(_ifModifiedSince);
final Date _pageDate;
switch (_header.getValue().getKey()) {
case STRING:
_pageDate = DateTimeUtils.parseDateTime((String) _header.getValue().getValue(), "EEE, dd MMM yyyy HH:mm:ss z", "0");
break;
case DATE:
_pageDate = new Date((Long) _header.getValue().getValue());
break;
default:
throw new IllegalArgumentException("Header " + _header + " is not supported as type: " + _header.getValue().getKey());
}
if (!_requestDate.before(_pageDate)) {
__response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
__response.setHeader("Last-Modified", __request.getHeader("If-Modified-Since"));
return;
}
}
}
}
}
//
__response.setContentType(__element.getContentType());
__doSetHeaders();
//
byte[] _body;
if (__element.isStoreGzipped() && StringUtils.contains(__request.getHeader("Accept-Encoding"), "gzip")) {
_body = __element.getGzippedBody();
if (_body.length == EMPTY_GZIPPED_CONTENT_SIZE) {
_body = new byte[0];
} else {
__response.setHeader("Content-Encoding", "gzip");
}
} else {
_body = __element.getUngzippedBody();
}
__response.setContentLength(_body.length);
OutputStream out = new BufferedOutputStream(__response.getOutputStream());
out.write(_body);
out.flush();
}
private void __doSetHeaders() {
for (final Map.Entry> _header : __element.getHeaders().entrySet()) {
final String name = _header.getKey();
if (_header.getValue() != null) {
switch (_header.getValue().getKey()) {
case STRING:
if (__response.containsHeader(name)) {
__response.addHeader(name, (String) _header.getValue().getValue());
} else {
__response.setHeader(name, (String) _header.getValue().getValue());
}
break;
case DATE:
if (__response.containsHeader(name)) {
__response.addDateHeader(name, (Long) _header.getValue().getValue());
} else {
__response.setDateHeader(name, (Long) _header.getValue().getValue());
}
break;
case INT:
if (__response.containsHeader(name)) {
__response.addIntHeader(name, (Integer) _header.getValue().getValue());
} else {
__response.setIntHeader(name, (Integer) _header.getValue().getValue());
}
break;
default:
throw new IllegalArgumentException("No mapping for Header: " + _header.getValue().getKey());
}
}
}
}
}