You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring MVC中禁用URL解码以保留加密参数中的加号

解决URL查询参数中加号被转成空格的问题

这个坑我之前踩过!问题根源在于HTTP协议的URL编码规范:查询参数里的+号默认会被解析为空格,但你的加密内容里+是有效字符,一旦被替换就没法正常解密了。下面给你几个实用的解决方案,按推荐程度排序:

1. 改用POST请求传递加密内容

这是最稳妥的方案,完全避开URL参数的编码问题。把加密值放在请求体(表单或JSON)里,Spring不会自动替换其中的+号。

示例代码(表单方式):

@RequestMapping(value = "missedcall", method = [RequestMethod.POST])
fun missedCall(@RequestParam("v") encryptedValue: String, model: ModelMap): String {
    // 这里的encryptedValue会完整保留原始的+号
    // 执行解密逻辑...
    return "处理结果"
}

示例代码(JSON方式):

如果加密内容较长,用JSON格式更规范:

// 定义请求体数据类
data class MissedCallRequest(val v: String)

@RequestMapping(
    value = "missedcall",
    method = [RequestMethod.POST],
    consumes = [MediaType.APPLICATION_JSON_VALUE]
)
fun missedCall(@RequestBody request: MissedCallRequest, model: ModelMap): String {
    val encryptedValue = request.v
    // 执行解密逻辑...
    return "处理结果"
}

2. 前端对加密内容做正确的URL编码

如果必须用GET请求,让前端在拼接URL时,用encodeURIComponent()对加密值进行编码,这样+会被转成%2B,后端解析时会自动还原成+。

前端示例(JavaScript):

const encryptedStr = "this+is+my+encrypted+string";
// 编码后得到 "this%2Bis%2Bmy%2Bencrypted%2Bstring"
const encodedStr = encodeURIComponent(encryptedStr);
const requestUrl = `http://myurl.com/missedcall?v=${encodedStr}`;

后端不用改代码,@RequestParam会自动把%2B解码为+,拿到正确的加密字符串。

3. 后端手动解析原始查询参数

如果前端没法修改,你可以直接从HttpServletRequest获取原始的查询字符串,自己解析参数,避开Spring自动替换+的逻辑。

示例代码:

@RequestMapping("missedcall")
fun missedCall(request: HttpServletRequest, model: ModelMap): String {
    val queryString = request.queryString ?: ""
    // 手动提取v参数的原始值
    val encryptedValue = queryString.split("&")
        .firstOrNull { it.startsWith("v=") }
        ?.substringAfter("v=")
    
    // 此时encryptedValue就是原始的"this+is+my+encrypted+string",保留了所有+号
    // 执行解密逻辑...
    return "处理结果"
}

4. 全局配置Spring MVC禁用参数自动解码

不推荐全局修改,但如果所有端点都需要保留+号,可以配置Spring MVC的UrlPathHelper,禁止自动解码请求参数:

配置类代码:

@Configuration
class WebMvcConfig : WebMvcConfigurer {
    override fun configurePathMatch(configurer: PathMatchConfigurer) {
        val urlPathHelper = UrlPathHelper()
        // 关闭自动解码,这样@RequestParam拿到的是编码后的原始字符串
        urlPathHelper.isUrlDecode = false
        configurer.urlPathHelper = urlPathHelper
    }
}

注意:这种情况下,你拿到的参数是编码后的字符串(比如this+is+my+encrypted+string),如果参数里还有其他需要解码的字符(比如%20),你需要手动调用URLDecoder.decode()处理,但要注意不要把+转成空格——可以先把+替换成%2B再解码:

val decodedValue = URLDecoder.decode(
    encryptedValue.replace("+", "%2B"),
    StandardCharsets.UTF_8.name()
)

内容的提问来源于stack exchange,提问作者Wheel Builder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:19:58