1
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
package com.budwk.app.web.commons.filter;
|
||||
|
||||
import org.nutz.lang.Strings;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
public class StaticResourceCacheFilter implements Filter {
|
||||
|
||||
private static final int ONE_YEAR_SECONDS = 31536000;
|
||||
private static final int SEVEN_DAYS_SECONDS = 604800;
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest request = (HttpServletRequest) req;
|
||||
HttpServletResponse response = (HttpServletResponse) res;
|
||||
applyCacheHeaders(request, response);
|
||||
chain.doFilter(req, res);
|
||||
}
|
||||
|
||||
private void applyCacheHeaders(HttpServletRequest request, HttpServletResponse response) {
|
||||
String path = Strings.sNull(request.getRequestURI());
|
||||
String contextPath = Strings.sNull(request.getContextPath());
|
||||
if (!contextPath.isBlank() && path.startsWith(contextPath)) {
|
||||
path = path.substring(contextPath.length());
|
||||
}
|
||||
if (!isStaticResourcePath(path)) {
|
||||
return;
|
||||
}
|
||||
response.setHeader("Vary", "Accept-Encoding");
|
||||
if (hasVersionQuery(request)) {
|
||||
setPublicCache(response, ONE_YEAR_SECONDS, true);
|
||||
return;
|
||||
}
|
||||
if (path.startsWith("/components/")) {
|
||||
response.setHeader("Cache-Control", "no-cache");
|
||||
return;
|
||||
}
|
||||
if (path.startsWith("/favicon/") || "/favicon.ico".equals(path)) {
|
||||
setPublicCache(response, SEVEN_DAYS_SECONDS, false);
|
||||
return;
|
||||
}
|
||||
if (isCacheableAsset(path)) {
|
||||
setPublicCache(response, SEVEN_DAYS_SECONDS, false);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isStaticResourcePath(String path) {
|
||||
return path.startsWith("/assets/") || path.startsWith("/components/") || path.startsWith("/favicon/") || "/favicon.ico".equals(path);
|
||||
}
|
||||
|
||||
private boolean hasVersionQuery(HttpServletRequest request) {
|
||||
String version = request.getParameter("v");
|
||||
return version != null && !version.isBlank();
|
||||
}
|
||||
|
||||
private boolean isCacheableAsset(String path) {
|
||||
String lowerPath = path.toLowerCase(Locale.ROOT);
|
||||
return lowerPath.endsWith(".js")
|
||||
|| lowerPath.endsWith(".css")
|
||||
|| lowerPath.endsWith(".png")
|
||||
|| lowerPath.endsWith(".jpg")
|
||||
|| lowerPath.endsWith(".jpeg")
|
||||
|| lowerPath.endsWith(".gif")
|
||||
|| lowerPath.endsWith(".webp")
|
||||
|| lowerPath.endsWith(".svg")
|
||||
|| lowerPath.endsWith(".ico")
|
||||
|| lowerPath.endsWith(".woff")
|
||||
|| lowerPath.endsWith(".woff2")
|
||||
|| lowerPath.endsWith(".ttf")
|
||||
|| lowerPath.endsWith(".eot")
|
||||
|| lowerPath.endsWith(".otf")
|
||||
|| lowerPath.endsWith(".map");
|
||||
}
|
||||
|
||||
private void setPublicCache(HttpServletResponse response, int maxAgeSeconds, boolean immutable) {
|
||||
String cacheControl = "public, max-age=" + maxAgeSeconds;
|
||||
if (immutable) {
|
||||
cacheControl += ", immutable";
|
||||
}
|
||||
response.setHeader("Cache-Control", cacheControl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.budwk.app.web.commons.filter;
|
||||
|
||||
import org.nutz.boot.AppContext;
|
||||
import org.nutz.boot.starter.WebFilterFace;
|
||||
import org.nutz.ioc.Ioc;
|
||||
import org.nutz.ioc.impl.PropertiesProxy;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@IocBean
|
||||
public class StaticResourceCacheFilterStarter implements WebFilterFace {
|
||||
|
||||
@Inject("refer:$ioc")
|
||||
protected Ioc ioc;
|
||||
|
||||
@Inject
|
||||
protected PropertiesProxy conf;
|
||||
|
||||
@Inject
|
||||
protected AppContext appContext;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "staticResourceCacheFilterStarter";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPathSpec() {
|
||||
return "/*";
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<DispatcherType> getDispatches() {
|
||||
return EnumSet.of(DispatcherType.REQUEST);
|
||||
}
|
||||
|
||||
@IocBean(name = "staticResourceCacheFilter")
|
||||
public StaticResourceCacheFilter createStaticResourceCacheFilter() {
|
||||
return new StaticResourceCacheFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter() {
|
||||
return ioc.get(StaticResourceCacheFilter.class, "staticResourceCacheFilter");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getInitParameters() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
@@ -149,7 +149,7 @@ public class CommonController {
|
||||
@ApiOperation("系统配置")
|
||||
public Result getConfigKey(String key) {
|
||||
Sys_config configKey = sysDictService.dao().fetch(Sys_config.class, Cnd.where("configKey", "=", key));
|
||||
return Result.success().addData(configKey.getConfigValue());
|
||||
return Result.success().addData(configKey == null ? "" : configKey.getConfigValue());
|
||||
}
|
||||
|
||||
@At
|
||||
|
||||
Reference in New Issue
Block a user