Java - преобразовать строку в допустимый объект URI

голоса
68

Я пытаюсь получить java.net.URIобъект из String. Строка имеют некоторые символы , которые нужны будут заменить их экранирующие последовательности процента. Но когда я использую URLEncoder для кодирования строки с UTF-8 кодировкой, даже / заменяются их управляющими последовательностями.

Как я могу получить действительный кодированный URL из объекта String?

http://www.google.com?q=a б дает HTTP% 3A% 2F% 2www.google.com ... в то время как я хочу выход быть http://www.google.com?q=a% 20b

Может кто-то пожалуйста, скажите мне, как достичь этого.

Я пытаюсь сделать это в Android приложение. Таким образом, у меня есть доступ к ограниченному числу библиотек.

Задан 21/02/2009 в 16:07
источник пользователем
На других языках...                            


11 ответов

голоса
55

Вы можете попробовать: org.apache.commons.httpclient.util.URIUtil.encodeQueryв Apache Обще-HTTPClient проекта

Как это (см URIUtil ):

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

станет:

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

Конечно, Вы можете сделать это самостоятельно, но URI разбор может получить довольно грязный ...

Ответил 21/02/2009 d 16:26
источник пользователем

голоса
45

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"));
Ответил 07/04/2011 d 16:21
источник пользователем

голоса
33

Я собираюсь добавить одно предложения здесь нацеленное на 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-адрес и его работу без необходимости каких-либо специальных знаний об этом самостоятельно.

Ответил 22/01/2012 d 18:02
источник пользователем

голоса
14

Даже если это старый пост с уже принятым ответом, я отправлю свой альтернативный ответ, потому что она хорошо работает для настоящего выпуска и, кажется, никто не упомянул этот метод.

С помощью библиотеки 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-адрес.

Ответил 06/08/2014 d 14:54
источник пользователем

голоса
9

Если вам не нравится, библиотеки, как об этом?

Обратите внимание, что вы не должны использовать эту функцию на весь URL, вместо этого вы должны использовать это на компонентах ... например, только компонент «аб», как вы строите вверх по 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;
}
Ответил 26/07/2010 d 08:07
источник пользователем

голоса
4

Я имел аналогичные проблемы для одного из моих проектов, чтобы создать объект 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);
Ответил 19/01/2012 d 21:47
источник пользователем

голоса
4

Вы можете использовать несколько аргументов конструкторов в URIклассе. Из URIJavadoc:

Многолетние аргумент Конструкторы процитировать недопустимые символы в соответствии с требованиями компонентов, в которых они появляются. Символ процента ( «%») всегда цитировала эти конструкторы. Любые другие символы сохраняются.

Так что если вы используете

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

После этого вы получите http:www.google.com?q=a%20bчто не совсем верно, но это немного ближе.

Если вы знаете , что ваша строка не будет иметь фрагменты URL (например , 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);

Чтобы быть в безопасности, вы должны сканировать строки для #символов, но это должно вам начать.

Ответил 21/02/2009 d 16:41
источник пользователем

голоса
3

Ну, я попытался с помощью

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

Я надеюсь, что это то, что вы на самом деле искали?

Ответил 12/07/2012 d 09:22
источник пользователем

голоса
1

Или, возможно, вы могли бы использовать этот класс:

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

Который присутствует в Android начиная с уровня API 1.

Досадно однако, он рассматривает пространства специально (заменяя их + вместо% 20). Чтобы обойти это, мы просто использовать этот фрагмент:

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

Ответил 12/01/2011 d 21:15
источник пользователем

голоса
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/

Ответил 21/02/2009 d 17:04
источник пользователем

голоса
0

Я закончил с использованием 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
Ответил 12/02/2015 d 04:51
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more