我在期待

System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8"));

输出:

你好%20世界

(20是ASCII十六进制空格码)

然而,我得到的是:

你好+世界

我用错方法了吗?我应该使用的正确方法是什么?


当前回答

只是在Android上也在挣扎,设法偶然发现了Uri。encode(字符串,字符串)而特定于android (android.net.Uri)可能对一些有用。

静态字符串编码(字符串s,字符串允许)

以https://developer.android.com/reference/android/net/Uri.html编码(以)

其他回答

虽然很老了,但还是迅速回应:

Spring提供了UriUtils -使用它你可以指定如何编码以及它与URI的哪个部分相关。

encodePathSegment
encodePort
encodeFragment
encodeUriVariables
....

我使用它们是因为我们已经在使用Spring,即不需要额外的库!

我用错方法了吗?我应该使用的正确方法是什么?

是的,这个方法java.net.URLEncoder.encode并不是根据规范将“”转换为“20%”。

空格字符“”被转换为加号“+”。

即使这不是正确的方法,您也可以将其修改为:System.out.println(java.net.URLEncoder.encode(“Hello World”,“UTF-8”)。replaceAll("\\+", "%20"));祝你今天愉快=)。

“+”是正确的。如果你真的需要%20,然后自己替换加。

警告:这个答案有很大的争议(+8 vs. -6),所以对这个答案持保留态度。

查询参数

org.apache.commons.httpclient.util.URIUtil
    URIUtil.encodeQuery(input);

如果你想转义URI中的字符

public static String escapeURIPathParam(String input) {
  StringBuilder resultStr = new StringBuilder();
  for (char ch : input.toCharArray()) {
   if (isUnsafe(ch)) {
    resultStr.append('%');
    resultStr.append(toHex(ch / 16));
    resultStr.append(toHex(ch % 16));
   } else{
    resultStr.append(ch);
   }
  }
  return resultStr.toString();
 }

 private static char toHex(int ch) {
  return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10);
 }

 private static boolean isUnsafe(char ch) {
  if (ch > 128 || ch < 0)
   return true;
  return " %$&+,/:;=?@<>#%".indexOf(ch) >= 0;
 }

其他答案要么提供手动字符串替换,实际上编码HTML格式的URLEncoder, Apache放弃的URIUtil,或者使用Guava的UrlEscapers。最后一个很好,除了它没有提供解码器。

Apache Commons Lang提供了URLCodec,它根据URL格式rfc3986进行编码和解码。

String encoded = new URLCodec().encode(str);
String decoded = new URLCodec().decode(str);

如果您已经在使用Spring,您也可以选择使用它的UriUtils类。