package com.ruoyi.common.utils.http; import java.util.HashMap; import java.util.Map; /** * 请求参数特殊字符转义工具类 * 用于处理HTTP请求参数中的特殊字符,防止XSS攻击和参数解析错误 */ public class ParameterEscaperUtil { // 特殊字符转义映射表 private static final Map ESCAPE_MAP; // 转义字符反转映射表 private static final Map UNESCAPE_MAP; static { // 初始化转义映射 ESCAPE_MAP = new HashMap<>(); ESCAPE_MAP.put('&', "&"); ESCAPE_MAP.put('<', "<"); ESCAPE_MAP.put('>', ">"); ESCAPE_MAP.put('"', """); ESCAPE_MAP.put('\'', "'"); ESCAPE_MAP.put('/', "/"); ESCAPE_MAP.put('\\', "\"); ESCAPE_MAP.put(' ', "%20"); ESCAPE_MAP.put('?', "%3F"); ESCAPE_MAP.put('=', "%3D"); ESCAPE_MAP.put('+', "%2B"); ESCAPE_MAP.put('%', "%25"); ESCAPE_MAP.put('#', "%23"); ESCAPE_MAP.put(':', "%3A"); ESCAPE_MAP.put(';', "%3B"); // 初始化反转义映射 UNESCAPE_MAP = new HashMap<>(); for (Map.Entry entry : ESCAPE_MAP.entrySet()) { UNESCAPE_MAP.put(entry.getValue(), entry.getKey()); } } /** * 转义请求参数中的特殊字符 * @param input 原始输入字符串 * @return 转义后的字符串 */ public static String escape(String input) { if (input == null || input.isEmpty()) { return input; } StringBuilder sb = new StringBuilder(); for (char c : input.toCharArray()) { // 如果是需要转义的字符,则使用转义后的字符串,否则直接添加 String escaped = ESCAPE_MAP.get(c); sb.append(escaped != null ? escaped : c); } return sb.toString(); } /** * 反转义请求参数中的特殊字符 * @param input 转义后的字符串 * @return 原始字符串 */ public static String unescape(String input) { if (input == null || input.isEmpty()) { return input; } StringBuilder sb = new StringBuilder(); int i = 0; while (i < input.length()) { boolean found = false; // 检查是否是转义序列 for (String escapeSeq : UNESCAPE_MAP.keySet()) { if (input.startsWith(escapeSeq, i)) { sb.append(UNESCAPE_MAP.get(escapeSeq)); i += escapeSeq.length(); found = true; break; } } if (!found) { sb.append(input.charAt(i)); i++; } } return sb.toString(); } }