Java中使用UriComponentsBuilder编码URL查询参数分号的问题
Java URL查询参数分号编码解决方案
问题描述
需要将URL查询参数中的分号(;)编码为%3B,但使用UriComponentsBuilder时出现两种异常:要么分号未被编码,要么手动编码后被双重编码为%253B。
问题原因
- 未编码的情况:
UriComponentsBuilder默认将分号视为URL查询参数中的合法分隔符(符合RFC规范),因此直接传入原始分号时不会触发编码。 - 双重编码的情况:如果先用
URLEncoder.encode将分号转为%3B,UriComponentsBuilder会把%识别为需要编码的字符,将其转为%25,最终得到%253B。手动替换分号为%3B后传入也会出现同样的双重编码问题。
正确解决方案
使用Spring提供的UriUtils.encodeQueryParam方法编码参数值,该方法会严格按照URL查询参数的规则编码,且不会被UriComponentsBuilder二次编码。
示例代码
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriUtils; import java.nio.charset.StandardCharsets; import java.util.Arrays; public class UrlEncodingExample { public static void main(String[] args) { String[] endpoints = {"endpoint1", "endpoint2"}; // 拼接带分号的原始字符串 String rawParam = String.join(";", Arrays.stream(endpoints).toArray(String[]::new)); // 用UriUtils编码查询参数 String encodedParam = UriUtils.encodeQueryParam(rawParam, StandardCharsets.UTF_8.name()); // 构建URI String finalUri = UriComponentsBuilder.fromPath("/foo/bar") .queryParam("target", encodedParam) .build() .toUriString(); System.out.println(finalUri); // 输出结果:/foo/bar?target=endpoint1%3Bendpoint2 } }
补充说明
如果不依赖Spring的UriUtils,也可以手动实现符合规则的编码,但需要确保只编码分号等需要转义的字符,同时避免对%重复编码。不过推荐使用成熟的工具类,避免手动编码出现遗漏或错误。
内容的提问来源于stack exchange,提问作者Andrey
相关产品推荐
相关产品推荐

