mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-04-01 16:23:24 +08:00
update 优化 统一补全代码注释
This commit is contained in:
@@ -20,6 +20,11 @@ import org.springframework.context.annotation.Bean;
|
||||
@EnableConfigurationProperties(XssProperties.class)
|
||||
public class FilterConfig {
|
||||
|
||||
/**
|
||||
* 注册 XSS 过滤器。
|
||||
*
|
||||
* @return XSS 请求过滤器实例
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
|
||||
@FilterRegistration(
|
||||
@@ -32,6 +37,11 @@ public class FilterConfig {
|
||||
return new XssFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册可重复读取请求体过滤器。
|
||||
*
|
||||
* @return 请求包装过滤器实例
|
||||
*/
|
||||
@Bean
|
||||
@FilterRegistration(name = "repeatableFilter", urlPatterns = "/*")
|
||||
public RepeatableFilter repeatableFilter() {
|
||||
|
||||
@@ -14,6 +14,11 @@ import org.springframework.web.servlet.LocaleResolver;
|
||||
@AutoConfiguration(before = WebMvcAutoConfiguration.class)
|
||||
public class I18nConfig {
|
||||
|
||||
/**
|
||||
* 注册自定义国际化区域解析器。
|
||||
*
|
||||
* @return Locale 解析器实例
|
||||
*/
|
||||
@Bean
|
||||
public LocaleResolver localeResolver() {
|
||||
return new I18nLocaleResolver();
|
||||
|
||||
@@ -25,12 +25,22 @@ import java.util.Date;
|
||||
@AutoConfiguration
|
||||
public class ResourcesConfig implements WebMvcConfigurer {
|
||||
|
||||
/**
|
||||
* 注册全局拦截器。
|
||||
*
|
||||
* @param registry 拦截器注册表
|
||||
*/
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 全局访问性能拦截
|
||||
registry.addInterceptor(new PlusWebInvokeTimeInterceptor());
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册全局格式转换器。
|
||||
*
|
||||
* @param registry 格式化器注册表
|
||||
*/
|
||||
@Override
|
||||
public void addFormatters(FormatterRegistry registry) {
|
||||
// 全局日期格式转换配置
|
||||
@@ -43,12 +53,19 @@ public class ResourcesConfig implements WebMvcConfigurer {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册静态资源处理器。
|
||||
*
|
||||
* @param registry 资源处理器注册表
|
||||
*/
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 跨域配置
|
||||
*
|
||||
* @return 全局 Cors 过滤器
|
||||
*/
|
||||
@Bean
|
||||
public CorsFilter corsFilter() {
|
||||
@@ -71,6 +88,8 @@ public class ResourcesConfig implements WebMvcConfigurer {
|
||||
|
||||
/**
|
||||
* 全局异常处理器
|
||||
*
|
||||
* @return 全局异常处理器实例
|
||||
*/
|
||||
@Bean
|
||||
public GlobalExceptionHandler globalExceptionHandler() {
|
||||
|
||||
@@ -12,6 +12,9 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@ConfigurationProperties(prefix = "captcha")
|
||||
public class CaptchaProperties {
|
||||
|
||||
/**
|
||||
* 是否启用验证码校验。
|
||||
*/
|
||||
private Boolean enable;
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* xss过滤 配置属性
|
||||
* XSS 过滤配置属性,用于控制过滤器开关及排除路径。
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@@ -16,12 +16,12 @@ import java.util.List;
|
||||
public class XssProperties {
|
||||
|
||||
/**
|
||||
* Xss开关
|
||||
* XSS 过滤总开关。
|
||||
*/
|
||||
private Boolean enabled;
|
||||
|
||||
/**
|
||||
* 排除路径
|
||||
* 跳过 XSS 过滤的请求路径集合。
|
||||
*/
|
||||
private List<String> excludeUrls = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ public class BaseController {
|
||||
|
||||
/**
|
||||
* 页面跳转
|
||||
*
|
||||
* @param url 目标跳转地址
|
||||
* @return Spring MVC 重定向路径表达式
|
||||
*/
|
||||
public String redirect(String url) {
|
||||
return StringUtils.format("redirect:{}", url);
|
||||
|
||||
@@ -7,12 +7,18 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 获取请求头国际化信息
|
||||
* 基于请求头解析国际化区域信息的语言解析器。
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public class I18nLocaleResolver implements LocaleResolver {
|
||||
|
||||
/**
|
||||
* 从请求头 {@code content-language} 中解析本次请求的区域信息,缺省时回退到系统默认区域。
|
||||
*
|
||||
* @param httpServletRequest 当前请求
|
||||
* @return 当前请求对应的区域设置
|
||||
*/
|
||||
@Override
|
||||
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
|
||||
String language = httpServletRequest.getHeader("content-language");
|
||||
@@ -23,6 +29,13 @@ public class I18nLocaleResolver implements LocaleResolver {
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前项目不在服务端主动切换区域信息,因此保留空实现。
|
||||
*
|
||||
* @param httpServletRequest 当前请求
|
||||
* @param httpServletResponse 当前响应
|
||||
* @param locale 目标区域
|
||||
*/
|
||||
@Override
|
||||
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.io.Serial;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* 带干扰线、波浪、圆的验证码
|
||||
* 带干扰线、波浪和圆形干扰元素的验证码实现,用于增强验证码识别难度。
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@@ -23,27 +23,70 @@ public class WaveAndCircleCaptcha extends AbstractCaptcha {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// 构造方法(略,与之前一致)
|
||||
/**
|
||||
* 构造默认长度为 4 的验证码。
|
||||
*
|
||||
* @param width 图片宽度
|
||||
* @param height 图片高度
|
||||
*/
|
||||
public WaveAndCircleCaptcha(int width, int height) {
|
||||
this(width, height, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造指定验证码长度的验证码对象。
|
||||
*
|
||||
* @param width 图片宽度
|
||||
* @param height 图片高度
|
||||
* @param codeCount 验证码字符数
|
||||
*/
|
||||
public WaveAndCircleCaptcha(int width, int height, int codeCount) {
|
||||
this(width, height, codeCount, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造指定字符数与干扰数的验证码对象。
|
||||
*
|
||||
* @param width 图片宽度
|
||||
* @param height 图片高度
|
||||
* @param codeCount 验证码字符数
|
||||
* @param interfereCount 干扰元素数量
|
||||
*/
|
||||
public WaveAndCircleCaptcha(int width, int height, int codeCount, int interfereCount) {
|
||||
this(width, height, new RandomGenerator(codeCount), interfereCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用指定验证码生成器构造验证码对象。
|
||||
*
|
||||
* @param width 图片宽度
|
||||
* @param height 图片高度
|
||||
* @param generator 验证码生成器
|
||||
* @param interfereCount 干扰元素数量
|
||||
*/
|
||||
public WaveAndCircleCaptcha(int width, int height, CodeGenerator generator, int interfereCount) {
|
||||
super(width, height, generator, interfereCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造带字体缩放比例的验证码对象。
|
||||
*
|
||||
* @param width 图片宽度
|
||||
* @param height 图片高度
|
||||
* @param codeCount 验证码字符数
|
||||
* @param interfereCount 干扰元素数量
|
||||
* @param size 字体相对尺寸
|
||||
*/
|
||||
public WaveAndCircleCaptcha(int width, int height, int codeCount, int interfereCount, float size) {
|
||||
super(width, height, new RandomGenerator(codeCount), interfereCount, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成验证码图片并绘制文字、扭曲效果及干扰图形。
|
||||
*
|
||||
* @param code 验证码文本
|
||||
* @return 生成后的验证码图片
|
||||
*/
|
||||
@Override
|
||||
public Image createImage(String code) {
|
||||
final BufferedImage image = new BufferedImage(
|
||||
@@ -65,6 +108,12 @@ public class WaveAndCircleCaptcha extends AbstractCaptcha {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制验证码文本并开启文字抗锯齿。
|
||||
*
|
||||
* @param g 图形上下文
|
||||
* @param code 验证码文本
|
||||
*/
|
||||
private void drawString(Graphics2D g, String code) {
|
||||
// 设置抗锯齿(让字体渲染更清晰)
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
@@ -77,6 +126,11 @@ public class WaveAndCircleCaptcha extends AbstractCaptcha {
|
||||
GraphicsUtil.drawStringColourful(g, code, this.font, this.width, this.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制圆形与波浪线干扰元素。
|
||||
*
|
||||
* @param g 图形上下文
|
||||
*/
|
||||
protected void drawInterfere(Graphics2D g) {
|
||||
ThreadLocalRandom random = RandomUtil.getRandom();
|
||||
int circleCount = Math.max(0, this.interfereCount - 1);
|
||||
@@ -98,6 +152,12 @@ public class WaveAndCircleCaptcha extends AbstractCaptcha {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制平滑波浪线干扰轨迹。
|
||||
*
|
||||
* @param g 图形上下文
|
||||
* @param random 随机数生成器
|
||||
*/
|
||||
private void drawSmoothWave(Graphics2D g, ThreadLocalRandom random) {
|
||||
int amplitude = random.nextInt(8) + 5; // 波动幅度
|
||||
int wavelength = random.nextInt(40) + 30; // 波长
|
||||
@@ -122,6 +182,14 @@ public class WaveAndCircleCaptcha extends AbstractCaptcha {
|
||||
g.drawPolyline(xPoints, yPoints, width);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成指定 RGB 范围内的随机颜色。
|
||||
*
|
||||
* @param min 最小颜色值
|
||||
* @param max 最大颜色值
|
||||
* @param random 随机数生成器
|
||||
* @return 随机颜色
|
||||
*/
|
||||
private Color getRandomColor(int min, int max, ThreadLocalRandom random) {
|
||||
int range = max - min;
|
||||
return new Color(
|
||||
|
||||
@@ -8,16 +8,32 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Repeatable 过滤器
|
||||
* 可重复读取请求体的过滤器,仅对 JSON 请求包装可重复消费的请求对象。
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class RepeatableFilter implements Filter {
|
||||
|
||||
/**
|
||||
* 过滤器初始化入口,当前无额外初始化逻辑。
|
||||
*
|
||||
* @param filterConfig 过滤器配置
|
||||
* @throws ServletException 过滤器初始化异常
|
||||
*/
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 为 JSON 请求创建可重复读取的包装器,便于日志、验签等场景多次读取请求体。
|
||||
*
|
||||
* @param request 原始请求
|
||||
* @param response 当前响应
|
||||
* @param chain 过滤器链
|
||||
* @throws IOException IO 异常
|
||||
* @throws ServletException Servlet 异常
|
||||
*/
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
@@ -33,6 +49,9 @@ public class RepeatableFilter implements Filter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤器销毁入口,当前无额外资源需要释放。
|
||||
*/
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
|
||||
@@ -15,13 +15,20 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* 构建可重复读取inputStream的request
|
||||
* 构建可重复读取输入流的请求包装器,缓存请求体以支持多次读取。
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
|
||||
private final byte[] body;
|
||||
|
||||
/**
|
||||
* 读取原始请求体并缓存到内存,统一设置请求与响应编码。
|
||||
*
|
||||
* @param request 原始请求
|
||||
* @param response 当前响应
|
||||
* @throws IOException 读取请求体异常
|
||||
*/
|
||||
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException {
|
||||
super(request);
|
||||
request.setCharacterEncoding(Constants.UTF8);
|
||||
@@ -30,11 +37,23 @@ public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
|
||||
body = IoUtil.readBytes(request.getInputStream(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于缓存的请求体构造字符读取器。
|
||||
*
|
||||
* @return 可重复读取的字符流
|
||||
* @throws IOException IO 异常
|
||||
*/
|
||||
@Override
|
||||
public BufferedReader getReader() throws IOException {
|
||||
return new BufferedReader(new InputStreamReader(getInputStream()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回基于缓存请求体重新生成的输入流。
|
||||
*
|
||||
* @return 可重复读取的输入流
|
||||
* @throws IOException IO 异常
|
||||
*/
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
|
||||
|
||||
@@ -13,22 +13,37 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 防止XSS攻击的过滤器
|
||||
* 防止 XSS 攻击的过滤器,对非排除请求执行参数与请求体清洗。
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class XssFilter implements Filter {
|
||||
/**
|
||||
* 排除链接
|
||||
* 跳过 XSS 过滤的请求路径集合。
|
||||
*/
|
||||
public List<String> excludes = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 初始化过滤器并加载配置中的排除路径。
|
||||
*
|
||||
* @param filterConfig 过滤器配置
|
||||
* @throws ServletException 过滤器初始化异常
|
||||
*/
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
XssProperties properties = SpringUtils.getBean(XssProperties.class);
|
||||
excludes.addAll(properties.getExcludeUrls());
|
||||
}
|
||||
|
||||
/**
|
||||
* 对请求执行 XSS 包装处理,命中排除规则时直接放行。
|
||||
*
|
||||
* @param request 原始请求
|
||||
* @param response 当前响应
|
||||
* @param chain 过滤器链
|
||||
* @throws IOException IO 异常
|
||||
* @throws ServletException Servlet 异常
|
||||
*/
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
@@ -42,6 +57,13 @@ public class XssFilter implements Filter {
|
||||
chain.doFilter(xssRequest, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前请求是否需要跳过 XSS 过滤。
|
||||
*
|
||||
* @param request 当前请求
|
||||
* @param response 当前响应
|
||||
* @return true 表示跳过过滤
|
||||
*/
|
||||
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {
|
||||
String url = request.getServletPath();
|
||||
String method = request.getMethod();
|
||||
@@ -52,6 +74,9 @@ public class XssFilter implements Filter {
|
||||
return StringUtils.matches(url, excludes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤器销毁入口,当前无额外资源需要释放。
|
||||
*/
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
|
||||
@@ -20,18 +20,27 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* XSS过滤处理
|
||||
* XSS 请求包装器,统一清洗参数与 JSON 请求体中的 HTML 标签内容。
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
/**
|
||||
* @param request
|
||||
* 使用原始请求构造 XSS 包装器。
|
||||
*
|
||||
* @param request 原始请求
|
||||
*/
|
||||
public XssHttpServletRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取并清洗单个请求参数。
|
||||
*
|
||||
* @param name 参数名
|
||||
* @return 清洗后的参数值
|
||||
*/
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
String value = super.getParameter(name);
|
||||
@@ -41,6 +50,11 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
return HtmlUtil.cleanHtmlTag(value).trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取并清洗整组请求参数。
|
||||
*
|
||||
* @return 清洗后的参数映射
|
||||
*/
|
||||
@Override
|
||||
public Map<String, String[]> getParameterMap() {
|
||||
Map<String, String[]> valueMap = super.getParameterMap();
|
||||
@@ -65,6 +79,12 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取并清洗指定参数的多值数组。
|
||||
*
|
||||
* @param name 参数名
|
||||
* @return 清洗后的参数值数组
|
||||
*/
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
String[] values = super.getParameterValues(name);
|
||||
@@ -80,6 +100,12 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
return escapseValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取输入流并在 JSON 场景下对请求体执行清洗。
|
||||
*
|
||||
* @return 清洗后的输入流
|
||||
* @throws IOException 读取请求体异常
|
||||
*/
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
// 非json类型,直接返回
|
||||
@@ -125,7 +151,9 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是Json请求
|
||||
* 判断当前请求是否为 JSON 请求。
|
||||
*
|
||||
* @return true 表示 JSON 请求
|
||||
*/
|
||||
public boolean isJsonRequest() {
|
||||
String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* web的调用时间统计拦截器
|
||||
* Web 调用时间统计拦截器,同时记录请求参数并对敏感字段做脱敏处理。
|
||||
*
|
||||
* @author Lion Li
|
||||
* @since 3.3.0
|
||||
@@ -36,6 +36,15 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final static ThreadLocal<StopWatch> KEY_CACHE = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 请求进入控制器前记录入参并启动耗时统计。
|
||||
*
|
||||
* @param request 当前请求
|
||||
* @param response 当前响应
|
||||
* @param handler 目标处理器
|
||||
* @return 始终返回 true,继续后续处理流程
|
||||
* @throws Exception 读取请求体或解析 JSON 失败时抛出
|
||||
*/
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
String url = request.getMethod() + " " + request.getRequestURI();
|
||||
@@ -71,6 +80,12 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归移除 JSON 节点中的敏感字段,避免在日志中输出密码等敏感信息。
|
||||
*
|
||||
* @param node 当前 JSON 节点
|
||||
* @param excludeProperties 需要排除的字段名集合
|
||||
*/
|
||||
private void removeSensitiveFields(JsonNode node, String[] excludeProperties) {
|
||||
if (node == null) {
|
||||
return;
|
||||
@@ -100,6 +115,15 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求完成后输出最终耗时,并清理线程内缓存的计时器。
|
||||
*
|
||||
* @param request 当前请求
|
||||
* @param response 当前响应
|
||||
* @param handler 目标处理器
|
||||
* @param ex 请求处理过程中的异常
|
||||
* @throws Exception 拦截器链路抛出的异常
|
||||
*/
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||
StopWatch stopWatch = KEY_CACHE.get();
|
||||
|
||||
Reference in New Issue
Block a user