创建 Java URL 时需要转义 '%'
Need to escape a '%' when creating a Java URL
我在创建有效的 URL 时遇到问题,因为它需要包含一些特殊字符。
String address = "...";
URL url = new URL(address);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();
InputStream input = url.openStream();
....
问题是我的地址需要包含一个&作为字符串中的一个字符,表示为%26。当我将地址创建为:
String address = "http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious";
... 变成
"http://foo.com/?animal=monkey&banana=fruit%20%2526%20delicious"
在 URL-to-URI-and-back 过程中。
解决此问题的最佳方法是什么?我是否在 URL/URI 转换中使用了最佳实践?如果是这样,有没有办法在 26 之前转义“%”,以便它最后仍然是 %26?
MCVE:
import java.util.*;
import java.io.*;
import java.net.*;
public class Test {
public static void main(String[] args) {
try {
String address = "http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious";
URL url = new URL(address);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();
System.out.println("url: " + url);
} catch (Exception e) {
System.out.println("Bad!");
}
}
}
航站楼 I/O:
$ javac Test.java
$ java Test
url: http://foo.com/?animal=monkey&banana=fruit%2520%2526%2520delicious
换句话说,我如何让它输出这个 URL:
url: http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious
进一步挖掘后,我无法使用此方法创建 URL。我需要使用仅采用单个字符串的 URI 构造函数。
我使用这段代码来找出差异并突出问题:
import java.util.*;
import java.io.*;
import java.net.*;
public class Test {
public static void main(String[] args) {
ArrayList<String> addresses = new ArrayList<String>();
addresses.add("http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious");
addresses.add("http://foo.com/?animal=monkey&banana=fruit %26 delicious");
addresses.add("http://foo.com/?animal=monkey&banana=fruit & delicious");
//addresses.add("http://foo.com/?animal=monkey&banana=fruit \%26 delicious"); this uses an illegal escape character
for (String address : addresses) {
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
try {
URL url = new URL(address);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
URL urlA = uri.toURL();
System.out.println("address: " + address);
System.out.println("yields: ");
System.out.println(" * urlA: " + urlA);
uri = new URI(address);
URL urlB = uri.toURL();
System.out.println(" * urlB: " + urlB);
} catch (Exception e) {
System.out.println(" Problem!");
}
}
}
}
在终端中产生了这个输出:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
address: http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious
yields:
* urlA: http://foo.com/?animal=monkey&banana=fruit%2520%2526%2520delicious
* urlB: http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
address: http://foo.com/?animal=monkey&banana=fruit %26 delicious
yields:
* urlA: http://foo.com/?animal=monkey&banana=fruit%20%2526%20delicious
Problem!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
address: http://foo.com/?animal=monkey&banana=fruit & delicious
yields:
* urlA: http://foo.com/?animal=monkey&banana=fruit%20&%20delicious
Problem!
第一次试的urlB的结果是唯一有效的。
我在创建有效的 URL 时遇到问题,因为它需要包含一些特殊字符。
String address = "...";
URL url = new URL(address);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();
InputStream input = url.openStream();
....
问题是我的地址需要包含一个&作为字符串中的一个字符,表示为%26。当我将地址创建为:
String address = "http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious";
... 变成
"http://foo.com/?animal=monkey&banana=fruit%20%2526%20delicious"
在 URL-to-URI-and-back 过程中。
解决此问题的最佳方法是什么?我是否在 URL/URI 转换中使用了最佳实践?如果是这样,有没有办法在 26 之前转义“%”,以便它最后仍然是 %26?
MCVE:
import java.util.*;
import java.io.*;
import java.net.*;
public class Test {
public static void main(String[] args) {
try {
String address = "http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious";
URL url = new URL(address);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();
System.out.println("url: " + url);
} catch (Exception e) {
System.out.println("Bad!");
}
}
}
航站楼 I/O:
$ javac Test.java
$ java Test
url: http://foo.com/?animal=monkey&banana=fruit%2520%2526%2520delicious
换句话说,我如何让它输出这个 URL:
url: http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious
进一步挖掘后,我无法使用此方法创建 URL。我需要使用仅采用单个字符串的 URI 构造函数。
我使用这段代码来找出差异并突出问题:
import java.util.*;
import java.io.*;
import java.net.*;
public class Test {
public static void main(String[] args) {
ArrayList<String> addresses = new ArrayList<String>();
addresses.add("http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious");
addresses.add("http://foo.com/?animal=monkey&banana=fruit %26 delicious");
addresses.add("http://foo.com/?animal=monkey&banana=fruit & delicious");
//addresses.add("http://foo.com/?animal=monkey&banana=fruit \%26 delicious"); this uses an illegal escape character
for (String address : addresses) {
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
try {
URL url = new URL(address);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
URL urlA = uri.toURL();
System.out.println("address: " + address);
System.out.println("yields: ");
System.out.println(" * urlA: " + urlA);
uri = new URI(address);
URL urlB = uri.toURL();
System.out.println(" * urlB: " + urlB);
} catch (Exception e) {
System.out.println(" Problem!");
}
}
}
}
在终端中产生了这个输出:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
address: http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious
yields:
* urlA: http://foo.com/?animal=monkey&banana=fruit%2520%2526%2520delicious
* urlB: http://foo.com/?animal=monkey&banana=fruit%20%26%20delicious
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
address: http://foo.com/?animal=monkey&banana=fruit %26 delicious
yields:
* urlA: http://foo.com/?animal=monkey&banana=fruit%20%2526%20delicious
Problem!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
address: http://foo.com/?animal=monkey&banana=fruit & delicious
yields:
* urlA: http://foo.com/?animal=monkey&banana=fruit%20&%20delicious
Problem!
第一次试的urlB的结果是唯一有效的。