2010-04-07 2 views
56

У меня есть строка, представляющая URL-адрес, содержащий пробелы, и вы хотите преобразовать его в объект URI. Если это просто попытка сделатьAndroid: howto parse URL String с пробелами для объекта URI?

String myString = "http://myhost.com/media/mp3s/9/Agenda of swine - 13. Persecution Ascension_ leave nothing standing.mp3"; 
URI myUri = new URI(myString); 

это дает мне

java.net.URISyntaxException: Illegal character in path at index X 

где индекс X является положение первого пробела в строке URL.

Как я могу разобрать myString в объект URI?

ответ

110

Вы должны на самом деле URI-encode «недопустимые» символы. Поскольку строка фактически содержит полный URL-адрес, трудно правильно кодировать URI-код. Вы не знаете, какие косынки / должны быть приняты во внимание, а какие нет. Вы не можете заранее предсказать это на необработанном String. Проблема действительно должна быть решена на более высоком уровне. Откуда у этого String? Это жестко? Тогда просто измените это самостоятельно. Он входит в качестве пользовательского ввода? Подтвердите его и покажите ошибку, позвольте пользователю решить проблему.

В любом случае, если вы можете гарантировать, что это только пробелы в URL, что делает его недействительным, то вы можете просто сделать струнный по струне заменить %20:

URI uri = new URI(string.replace(" ", "%20")); 

Или, если вы можете быть уверены, что это только часть после последнего слеша, который должен быть URI-закодирован, то вы можете просто сделать это с помощью android.net.Uri утилиты класса:

int pos = string.lastIndexOf('/') + 1; 
URI uri = new URI(string.substring(0, pos) + Uri.encode(string.substring(pos))); 

Обратите внимание, что URLEncoder является незаменимым для задачи, поскольку он предназначен для кодирования имен/значений параметров строки запроса в соответствии с правилами application/x-www-form-urlencoded (как используется в HTML-формах). См. Также Java URL encoding of query string parameters.

+1

Замена пробелов '% 20' на трюк. THX – Mannaz

+4

@Mannaz - будьте осторожны, когда в названии песни появляется еще один «недействительный» символ. – Bozho

+0

@BalusC я попробовал URLEncoder.encode («строка запроса», «UTF-8»); его возвращение с символом +, как этот «запрос + строка», где im ожидает «% 20». Поэтому я использовал string.replace с жестко закодированными значениями. Решила проблему. Спасибо за информацию. Есть ли другие пути для кодирования вместо ручной замены?? – praveenb

19
java.net.URLEncoder.encode(finalPartOfString, "utf-8"); 

Это будет URL-encode строка.

finalPartOfString - часть после последней косой черты - в вашем случае, название песни, как кажется.

+2

Он также будет указывать двоеточие и косые черты, которые сделают URL еще недействительным. В основном он должен только прокручивать пробелы, чтобы получить его. – BalusC

+0

@BalusC, спасибо, я добавил обновление. – Bozho

+0

Хорошо, это получает меня от URISyntaxException, но теперь я получаю 404 с сервера. URL-адрес, который я получаю: http: //myhost.com/media/mp3s/9/Agenda+of+swine + - + 13. + Преследование + Вознесение + оставить + ничего + стоять.mp3'. Я использую URI в 'org.apache.http.client.methods.HttpGet.Запрос HttpGet'. Есть идеи? – Mannaz

1

Для обработки пространства, @ и другие небезопасные символы в произвольных местах, в пути URL-адрес, использование Uri.Builder в сочетании с локальным экземпляром URL, как я описал here:

private Uri.Builder builder; 
public Uri getUriFromUrl(String thisUrl) { 
    URL url = new URL(thisUrl); 
    builder = new Uri.Builder() 
          .scheme(url.getProtocol()) 
          .authority(url.getAuthority()) 
          .appendPath(url.getPath()); 
    return builder.build(); 
} 
0
URL url = Test.class.getResource(args[0]); // reading demo file path from             
              // same location where class          
File input=null; 
try { 
    input = new File(url.toURI()); 
} catch (URISyntaxException e1) { 
    // TODO Auto-generated catch block 
    e1.printStackTrace(); 
} 
+0

почему отрицательная маркировка? – siddmuk2005

+0

, потому что это не отвечает на вопрос. – MetaFight

+1

Я дал это для удаления пространства из URL-адреса, чтобы он разрешил мою проблему, потому что, читая расположение файла, FileInputStream указывает на нуль, а при чтении с нулевым значением он будет генерировать Exception bu, используя URI, я не получил проблему. – siddmuk2005

0

Я написал эту функцию:

public static String encode(@NonNull String uriString) { 
    if (TextUtils.isEmpty(uriString)) { 
     Assert.fail("Uri string cannot be empty!"); 
     return uriString; 
    } 
    // getQueryParameterNames is not exist then cannot iterate on queries 
    if (Build.VERSION.SDK_INT < 11) { 
     return uriString; 
    } 

    // Check if uri has valid characters 
    // See https://tools.ietf.org/html/rfc3986 
    Pattern allowedUrlCharacters = Pattern.compile("([A-Za-z0-9_.~:/?\\#\\[\\]@!$&'()*+,;" + 
      "=-]|%[0-9a-fA-F]{2})+"); 
    Matcher matcher = allowedUrlCharacters.matcher(uriString); 
    String validUri = null; 
    if (matcher.find()) { 
     validUri = matcher.group(); 
    } 
    if (TextUtils.isEmpty(validUri) || uriString.length() == validUri.length()) { 
     return uriString; 
    } 

    // The uriString is not encoded. Then recreate the uri and encode it this time 
    Uri uri = Uri.parse(uriString); 
    Uri.Builder uriBuilder = new Uri.Builder() 
      .scheme(uri.getScheme()) 
      .authority(uri.getAuthority()); 
    for (String path : uri.getPathSegments()) { 
     uriBuilder.appendPath(path); 
    } 
    for (String key : uri.getQueryParameterNames()) { 
     uriBuilder.appendQueryParameter(key, uri.getQueryParameter(key)); 
    } 
    String correctUrl = uriBuilder.build().toString(); 
    return correctUrl; 
} 
Смежные вопросы