java.net.URI()。getPath()返回null,而字符串包含冒号?

时间:2018-05-29 02:54:52

标签: java

准确地说,请考虑以下字符串示例:

String str = ":Royal%2Bweddings%3A%2Bceremony%2BThe%2Bsymbolism";
java.net.URI(str).getPath();

这里因为str包含:冒号,URI().getPath()返回null但是如果我删除了冒号,则返回值就像我预期的那样。

那么如何让URI().getPath()不过滤冒号并将其保留原样呢?

2 个答案:

答案 0 :(得分:2)

首先,关于代码的一些事情。它无法编译,因为您需要使用new来创建新对象:

String str = ":Royal%2Bweddings%3A%2Bceremony%2BThe%2Bsymbolism";
new java.net.URI(str).getPath();

该代码不返回null - 而是抛出描述性异常:

java.net.URISyntaxException: Expected scheme name at index 0: :Royal%2Bweddings%3A%2Bceremony%2BThe%2Bsymbolism

URI构造函数采用完整的URI,冒号具有特殊含义 - 但它需要以协议名称为前缀,如http:file:

如果要在路径中使用这些特殊字符,则需要对路径进行URL编码 - 这是在URL或URI中包含特殊字符的常规做法:

String str = ":Royal%2Bweddings%3A%2Bceremony%2BThe%2Bsymbolism";
str = URLEncoder.encode(str, "UTF-8"); // <---- URL encoding
System.out.println(new java.net.URI(str).getPath());

您不需要使用自己的替换来提出自己的编码方案 - URL是标准。而且您也不需要解码,由getPath()自动处理。

但是在您的情况下,您的路径已经部分进行了网址编码 - 并且它已经包含一个冒号:Royal+weddings:+ceremony+The+symbolism

您需要一次性对整个路径进行URL编码:

String encoded = URLEncoder.encode(":Royal+weddings:+ceremony+The+symbolism", "UTF-8");

然后你就安定下来了。

答案 1 :(得分:0)

您可以按照以下方式尝试从冒号字符“转义”(使用URLEncoder建议使用Scary Wombat):

import java.net.*;
import java.io.*;

public class MyClass {

public static void main(String args[]) {
    try { 
        String str = "https://www.jdoodle.com/online-ja:va-compiler"; 
        String escapedStr = URLEncoder.encode(str, "UTF-8");
        System.out.println(escapedStr);
        String uriPath = new java.net.URI(escapedStr).getPath();
        System.out.println(uriPath);

    } catch (URISyntaxException |  UnsupportedEncodingException e) { 
        e.printStackTrace(); // just for the sake of this example, this should be logged properly
    }
}

}

输出是:

https%3A%2F%2Fwww.jdoodle.com%2Fonline-ja%3Ava-compiler // note the UTF-8 representation for potentially problematic characters
https://www.jdoodle.com/online-ja:va-compiler

最初建议的方法是使用子字符串替换的概念来逃避有问题的字符(取决于代码的业务逻辑) - 请注意,这是一种通用案例方法,不适合URI处理:

public class Escaping {

private static final String COLON = ":";
private static final String ESCAPE_COLON = ".colon.";

public static void main(String args[]) {
    String str = "This is my : String : with colons"; 
    String escapedStr = str.replaceAll(COLON,ESCAPE_COLON);
    System.out.println(escapedStr);
    // perfrom whatever action you need with the 'problematic' colon characters
    // ...
    // ...
    System.out.println(escapedStr.replaceAll(ESCAPE_COLON,COLON));
    }
}

输出:

This is my .colon. String .colon. with colons
This is my : String : with:

参考文献: