含冒号字符串调用java.net.URI().getPath()返回null,如何保留冒号?
解决URI.getPath()因开头冒号返回null的问题
这个问题我之前也碰到过,核心是URI的自动解析规则在作祟,咱们一步步拆解解决:
问题原因
当你直接用带开头冒号的字符串构造URI时,解析器会把开头的:当作scheme(协议)和路径的分隔符。但你的字符串开头只有冒号,没有合法的scheme名称(比如http:里的http),这就导致URI无法正确识别路径部分,最终getPath()返回null。
看你的示例代码:
String str = ":Royal%2Bweddings%3A%2Bceremony%2BThe%2Bsymbolism"; System.out.println(new URI(str).getPath()); // 输出null
这里的:被误判为scheme分隔符,而空scheme不符合URI规范,所以路径解析失败。
解决方案
要让冒号被当作路径的一部分保留,你需要绕过URI的自动scheme解析逻辑,明确告诉URI这就是路径内容。可以用以下两种方法实现:
方法1:直接构造带指定路径的URI
使用URI(String scheme, String authority, String path, String query, String fragment)这个构造函数,把scheme和authority设为null,只传入你的字符串作为path参数:
import java.net.URI; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; public class URITest { public static void main(String[] args) throws Exception { String str = ":Royal%2Bweddings%3A%2Bceremony%2BThe%2Bsymbolism"; // 明确指定路径,绕过scheme解析 URI uri = new URI(null, null, str, null, null); // 获取原始编码的路径 String encodedPath = uri.getPath(); System.out.println("编码后的路径: " + encodedPath); // 输出::Royal%2Bweddings%3A%2Bceremony%2BThe%2Bsymbolism // 如果需要解码后的路径 String decodedPath = URLDecoder.decode(encodedPath, StandardCharsets.UTF_8); System.out.println("解码后的路径: " + decodedPath); // 输出:Royal:weddings:ceremony:The:symbolism } }
方法2:先编码开头的冒号(可选)
如果你想让开头的冒号也被编码(变成%3A),再构造URI,这样也能避免scheme解析问题:
String str = ":Royal%2Bweddings%3A%2Bceremony%2BThe%2Bsymbolism"; // 把开头的冒号编码为%3A String encodedStr = str.replaceFirst("^:", "%3A"); URI uri = new URI(encodedStr); System.out.println(uri.getPath()); // 输出:%3ARoyal%2Bweddings%3A%2Bceremony%2BThe%2Bsymbolism
这种方法适合你需要保留所有编码字符的场景。
总结
核心思路就是不让URI把开头的冒号误判为scheme分隔符,要么明确指定路径参数,要么提前编码开头的冒号,两种方法都能让getPath()正确返回包含冒号的路径内容。
内容的提问来源于stack exchange,提问作者ITried
相关产品推荐
相关产品推荐

