From 448a7006870b7e7d3742ba8b919332762495365b Mon Sep 17 00:00:00 2001 From: Moomel Date: Wed, 21 Feb 2024 02:56:54 +0000 Subject: [PATCH] =?UTF-8?q?!253=20=E4=BF=AE=E5=A4=8D=EF=BC=9A=E9=9D=9E?= =?UTF-8?q?=E6=B3=95=E8=AF=B7=E6=B1=82=E4=BD=BF=E8=BF=87=E6=BB=A4=E5=99=A8?= =?UTF-8?q?=E5=A4=B1=E6=95=88=EF=BC=8C=E5=87=BA=E7=8E=B0=E4=B8=A5=E9=87=8D?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E9=97=AE=E9=A2=98=20*=20BaseUrlFilter=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=BF=87=E6=BB=A4=E5=85=A8=E9=83=A8=E8=B7=AF?= =?UTF-8?q?=E5=BE=84,=E4=BF=9D=E8=AF=81=20BaseUrlFilter=20=E4=BC=98?= =?UTF-8?q?=E4=BA=8EUrlCheckFilter=20=E6=89=A7=E8=A1=8C=20*=20=E6=B8=85?= =?UTF-8?q?=E9=99=A4=E6=97=A0=E7=94=A8=20html=20*=20=E9=9D=9E=E6=B3=95?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E8=BF=87=E6=BB=A4=E5=99=A8:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=AF=B7=E6=B1=82=20path=20=E4=B8=AD=E5=8C=85?= =?UTF-8?q?=E5=90=AB=20//=20=E6=88=96=E8=80=85=E4=BB=A5=20/=20=E7=BB=93?= =?UTF-8?q?=E5=B0=BE=E5=AF=BC=E8=87=B4=E5=85=B6=E5=AE=83=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E5=99=A8=E5=A4=B1=E6=95=88=EF=BC=8C=E5=AF=B9=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E9=87=8D=E5=AE=9A=E5=90=91=20*=20=E9=9D=9E?= =?UTF-8?q?=E6=B3=95=E8=AF=B7=E6=B1=82=E8=BF=87=E6=BB=A4=E5=99=A8:=20?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=20getRequestURI()=20=E4=B8=BA=20getServletPa?= =?UTF-8?q?th()=20*=20=E9=9D=9E=E6=B3=95=E8=AF=B7=E6=B1=82=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E5=99=A8:=20=E6=88=AA=E5=8F=96=20context-path=20*=20?= =?UTF-8?q?=E9=9D=9E=E6=B3=95=E8=AF=B7=E6=B1=82=E8=BF=87=E6=BB=A4=E5=99=A8?= =?UTF-8?q?:=20=E5=8E=BB=E9=99=A4=20context-path=20*=20=E9=9D=9E=E6=B3=95?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E8=BF=87=E6=BB=A4=E5=99=A8:=20=E6=8E=92?= =?UTF-8?q?=E9=99=A4=E9=A6=96=E9=A1=B5path=20"/"=20*=20=E9=9D=9E=E6=B3=95?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E8=BF=87=E6=BB=A4=E5=99=A8:=20=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E5=9C=B0=E5=9D=80=E4=B8=AD=E5=8C=85=E5=90=AB"//"?= =?UTF-8?q?=E6=88=96=E8=80=85=E4=BB=A5"/"=E7=BB=93=E5=B0=BE=E6=97=B6?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E5=85=B6=E4=BB=96=E8=BF=87=E6=BB=A4=E5=99=A8?= =?UTF-8?q?=E5=A4=B1=E6=95=88=EF=BC=8C=E6=AF=94=E5=A6=82=20TrustHostFilter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/cn/keking/config/WebConfig.java | 16 ++++-- .../cn/keking/web/filter/UrlCheckFilter.java | 52 +++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 server/src/main/java/cn/keking/web/filter/UrlCheckFilter.java diff --git a/server/src/main/java/cn/keking/config/WebConfig.java b/server/src/main/java/cn/keking/config/WebConfig.java index dd67070d..eb85367d 100644 --- a/server/src/main/java/cn/keking/config/WebConfig.java +++ b/server/src/main/java/cn/keking/config/WebConfig.java @@ -30,11 +30,13 @@ public class WebConfig implements WebMvcConfigurer { registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/","classpath:/resources/","classpath:/static/","classpath:/public/","file:" + filePath); } + @Bean public FilterRegistrationBean getChinesePathFilter() { ChinesePathFilter filter = new ChinesePathFilter(); FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(filter); + registrationBean.setOrder(10); return registrationBean; } @@ -67,14 +69,20 @@ public class WebConfig implements WebMvcConfigurer { @Bean public FilterRegistrationBean getBaseUrlFilter() { Set filterUri = new HashSet<>(); - filterUri.add("/index"); - filterUri.add("/"); - filterUri.add("/onlinePreview"); - filterUri.add("/picturesPreview"); BaseUrlFilter filter = new BaseUrlFilter(); FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(filter); registrationBean.setUrlPatterns(filterUri); + registrationBean.setOrder(20); + return registrationBean; + } + + @Bean + public FilterRegistrationBean getUrlCheckFilter() { + UrlCheckFilter filter = new UrlCheckFilter(); + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(filter); + registrationBean.setOrder(30); return registrationBean; } diff --git a/server/src/main/java/cn/keking/web/filter/UrlCheckFilter.java b/server/src/main/java/cn/keking/web/filter/UrlCheckFilter.java new file mode 100644 index 00000000..572486f9 --- /dev/null +++ b/server/src/main/java/cn/keking/web/filter/UrlCheckFilter.java @@ -0,0 +1,52 @@ +package cn.keking.web.filter; + +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @date 2023/11/30 + */ +public class UrlCheckFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + + final HttpServletRequest httpServletRequest = (HttpServletRequest) request; + String servletPath = httpServletRequest.getServletPath(); + + boolean redirect = false; + + // servletPath 中不能包含 // + if (servletPath.contains("//")) { + servletPath = servletPath.replaceAll("//+", "/"); + redirect = true; + } + + // 不能以 / 结尾,同时考虑 **首页** 的特殊性 + if (servletPath.endsWith("/") && servletPath.length() > 1) { + servletPath = servletPath.substring(0, servletPath.length() - 1); + redirect = true; + } + if (redirect) { + String redirectUrl; + if (StringUtils.isBlank(BaseUrlFilter.getBaseUrl())) { + // 正常 BaseUrlFilter 有限此 Filter 执行,不会执行到此 + redirectUrl = httpServletRequest.getContextPath() + servletPath; + } else { + if (BaseUrlFilter.getBaseUrl().endsWith("/") && servletPath.startsWith("/")) { + // BaseUrlFilter.getBaseUrl() 以 / 结尾,servletPath 以 / 开头,需再去除一次 // + redirectUrl = BaseUrlFilter.getBaseUrl() + servletPath.substring(1); + } else { + redirectUrl = BaseUrlFilter.getBaseUrl() + servletPath; + } + } + ((HttpServletResponse) response).sendRedirect(redirectUrl + "?" + httpServletRequest.getQueryString()); + } else { + chain.doFilter(request, response); + } + } +}