首页 文章

Java - 将String转换为有效的URI对象

提问于
浏览
69

我试图从 String 获得一个 java.net.URI 对象 . 该字符串有一些字符需要用它们的百分比转义序列替换 . 但是当我使用URLEncoder对UTF-8编码的字符串进行编码时,即使/被替换为它们的转义序列 .

如何从String对象获取有效的编码URL?

http://www.google.com?q=a b 给出 http%3A%2F%2www.google.com... 而我希望输出为 http://www.google.com?q=a%20b

有人可以告诉我如何实现这一目标 .

我试图在Android应用程序中执行此操作 . 所以我可以访问有限数量的库 .

11 回答

  • 4

    您可以尝试:Apache commons-httpclientApache commons-httpclient项目中

    像这样(见URIUtil):

    URIUtil.encodeQuery("http://www.google.com?q=a b")
    

    会变成:

    http://www.google.com?q=a%20b
    

    你当然可以自己做,但URI解析会变得相当混乱......

  • 9

    Android一直将Uri类作为SDK的一部分:http://developer.android.com/reference/android/net/Uri.html

    您可以简单地执行以下操作:

    String requestURL = String.format("http://www.example.com/?a=%s&b=%s", Uri.encode("foo bar"), Uri.encode("100% fubar'd"));
    
  • 4

    我将在这里针对Android用户添加一个建议 . 您可以这样做,避免必须获得任何外部库 . 此外,在上面的一些答案中建议的所有搜索/替换字符解决方案都是危险的,应该避免 .

    尝试一下:

    String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4";
    URL url = new URL(urlStr);
    URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
    url = uri.toURL();
    

    你可以看到,在这个特定的URL中,我需要对这些空间进行编码,以便我可以将它用于请求 .

    这利用了Android类中可用的一些功能 . 首先,URL类可以将url分解为其正确的组件,因此您无需进行任何字符串搜索/替换工作 . 其次,当您通过组件而不是单个字符串构造URI时,此方法利用了正确转义组件的URI类功能 .

    这种方法的优点在于,您可以使用任何有效的URL字符串并使其工作,而无需您自己了解任何特殊知识 .

  • 55

    即使这是一个已经被接受的答案的旧帖子,我发布我的替代答案,因为它适用于当前的问题,似乎没有人提到这种方法 .

    使用java.net.URI库:

    URI uri = URI.create(URLString);
    

    如果你想要一个与之对应的URL格式的字符串:

    String validURLString = uri.toASCIIString();
    

    与许多其他方法(例如java.net.URLEncoder)不同,此方法仅替换不安全的ASCII字符(如 çé ...) .


    在上面的示例中,如果 URLString 是以下 String

    "http://www.domain.com/façon+word"
    

    结果 validURLString 将是:

    "http://www.domain.com/fa%C3%A7on+word"
    

    这是一个格式良好的URL .

  • 45

    如果你不喜欢图书馆,那怎么样?

    请注意,您不应在整个URL上使用此功能,而应在组件上使用此功能...例如 . 只是“a b”组件,当你 Build URL时 - 否则计算机将不知道哪些字符应该具有特殊含义以及哪些字符应具有字面含义 .

    /** Converts a string into something you can safely insert into a URL. */
    public static String encodeURIcomponent(String s)
    {
        StringBuilder o = new StringBuilder();
        for (char ch : s.toCharArray()) {
            if (isUnsafe(ch)) {
                o.append('%');
                o.append(toHex(ch / 16));
                o.append(toHex(ch % 16));
            }
            else o.append(ch);
        }
        return o.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;
    }
    
  • 14

    您可以使用 URI 类的多参数构造函数 . 来自 URI javadoc:

    多参数构造函数引用它们出现的组件所需的非法字符 . 百分比字符('%')始终由这些构造函数引用 . 保留任何其他字符 .

    所以,如果你使用

    URI uri = new URI("http", "www.google.com?q=a b");
    

    然后你得到 http:www.google.com?q=a%20b ,这不是更近了 .

    如果您知道您的字符串不会包含网址片段(例如http://example.com/page#anchor),那么您可以使用以下代码获取所需内容:

    String s = "http://www.google.com?q=a b";
    String[] parts = s.split(":",2);
    URI uri = new URI(parts[0], parts[1], null);
    

    为了安全起见,您应该扫描字符串中的 # 个字符,但这应该可以帮助您入门 .

  • 33

    我的一个项目有一个类似的问题,从字符串创建一个URI对象 . 我也找不到任何干净的解决方案 . 这是我想出的:

    public static URI encodeURL(String url) throws MalformedURLException, URISyntaxException  
    {
        URI uriFormatted = null; 
    
        URL urlLink = new URL(url);
        uriFormatted = new URI("http", urlLink.getHost(), urlLink.getPath(), urlLink.getQuery(), urlLink.getRef());
    
        return uriFormatted;
    }
    

    您可以使用以下URI构造函数来指定端口(如果需要):

    URI uri = new URI(scheme, userInfo, host, port, path, query, fragment);
    
  • 0

    好吧,我试过用

    String converted = URLDecoder.decode("toconvert","UTF-8");
    

    我希望这是你真正想要的?

  • 1

    java.net博客前几天有一个类可能已经完成了你想要的东西(但它现在已经关闭,所以我无法检查) .

    这里的代码可能会被修改为你想要的:

    http://svn.apache.org/repos/asf/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/UriBuilder.java

    这是我在java.net中想到的那个:https://urlencodedquerystring.dev.java.net/

  • 1

    或许你可以使用这个类:

    http://developer.android.com/reference/java/net/URLEncoder.html

    从API级别1开始在Android中出现 .

    然而,令人讨厌的是,它专门处理空间(用%而不是%20代替它们) . 为了解决这个问题,我们只需使用这个片段:

    URLEncoder.encode(value, "UTF-8").replace("+", "%20");

  • 3

    我最终使用了httpclient-4.3.6:

    import org.apache.http.client.utils.URIBuilder;
    public static void main (String [] args) {
        URIBuilder uri = new URIBuilder();
        uri.setScheme("http")
        .setHost("www.example.com")
        .setPath("/somepage.php")
        .setParameter("username", "Hello Günter")
        .setParameter("p1", "parameter 1");
        System.out.println(uri.toString());
    }
    

    输出会是:

    http://www.example.com/somepage.php?username=Hello+G%C3%BCnter&p1=paramter+1
    

相关问题