Как бороться с URISyntaxException - PullRequest
       19

Как бороться с URISyntaxException

39 голосов
/ 15 апреля 2009

Я получил это сообщение об ошибке:

java.net.URISyntaxException: Illegal character in query at index 31: http://finance.yahoo.com/q/h?s=^IXIC

My_Url = http://finance.yahoo.com/q/h?s=^IXIC

Когда я скопировал его в поле адреса браузера, он показал правильную страницу, это действительный URL, но я не могу разобрать это с помощью: new URI(My_Url)

Я пытался: My_Url=My_Url.replace("^","\\^"), но

  1. Это не тот URL, который мне нужен
  2. Это тоже не работает

Как с этим справиться?

Frank

Ответы [ 9 ]

55 голосов
/ 15 апреля 2009

Вам необходимо закодировать URI, чтобы заменить недопустимые символы допустимыми закодированными символами. Если вы сначала создадите URL-адрес (чтобы вам не приходилось выполнять синтаксический анализ самостоятельно), а затем создадите URI с помощью конструктора с пятью аргументами , тогда этот конструктор сделает кодировку за вас.

import java.net.*;

public class Test {
  public static void main(String[] args) {
    String myURL = "http://finance.yahoo.com/q/h?s=^IXIC";
    try {
      URL url = new URL(myURL);
      String nullFragment = null;
      URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), nullFragment);
      System.out.println("URI " + uri.toString() + " is OK");
    } catch (MalformedURLException e) {
      System.out.println("URL " + myURL + " is a malformed URL");
    } catch (URISyntaxException e) {
      System.out.println("URI " + myURL + " is a malformed URL");
    }
  }
}
18 голосов
/ 15 апреля 2009

Используйте кодировку % для символа ^, а именно. http://finance.yahoo.com/q/h?s=%5EIXIC

14 голосов
/ 15 апреля 2009

Вы должны закодировать свои параметры.

Что-то вроде этого подойдет:

import java.net.*;
import java.io.*;

public class EncodeParameter { 

    public static void main( String [] args ) throws URISyntaxException ,
                                         UnsupportedEncodingException   { 

        String myQuery = "^IXIC";

        URI uri = new URI( String.format( 
                           "http://finance.yahoo.com/q/h?s=%s", 
                           URLEncoder.encode( myQuery , "UTF8" ) ) );

        System.out.println( uri );

    }
}

http://java.sun.com/javase/6/docs/api/java/net/URLEncoder.html

4 голосов
/ 13 апреля 2016

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

String link = "http://foo.com";
URL url = null;
URI uri = null;

try {
   url = new URL(link);
} catch(MalformedURLException e) {
   e.printStackTrace();
}

try{
   uri = new URI(url.toString)
} catch(URISyntaxException e {
   try {
        uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),
                      url.getPort(), url.getPath(), url.getQuery(), 
                      url.getRef());
   } catch(URISyntaxException e1 {
        e1.printStackTrace();
   }
}
try {
   url = uri.toURL()
} catch(MalfomedURLException e) {
   e.printStackTrace();
}

String encodedLink = url.toString();
1 голос
/ 02 января 2014

Общее решение требует парсинга URL в URI, совместимый с RFC 2396 (обратите внимание, что это старая версия стандарта URI, которую использует java.net.URI).

Я написал библиотеку разбора URL Java, которая делает это возможным: galimatias . С помощью этой библиотеки вы можете добиться желаемого поведения с помощью этого кода:

String urlString = //...
URLParsingSettings settings = URLParsingSettings.create()
  .withStandard(URLParsingSettings.Standard.RFC_2396);
URL url = URL.parse(settings, urlString);

Обратите внимание, что galimatias находится на очень ранней стадии, и некоторые функции являются экспериментальными, но он уже достаточно тверд для этого варианта использования.

1 голос
/ 22 марта 2013

Не представляю ничего лучшего для
http://server.ru:8080/template/get?type=mail&format=html&key=ecm_task_assignment&label=Согласовать с контрагентом & descr = Описание & objectid = 2231
что:

public static boolean checkForExternal(String str) {
    int length = str.length();
    for (int i = 0; i < length; i++) {
        if (str.charAt(i) > 0x7F) {
            return true;
        }
    }
    return false;
}

private static final Pattern COLON = Pattern.compile("%3A", Pattern.LITERAL);
private static final Pattern SLASH = Pattern.compile("%2F", Pattern.LITERAL);
private static final Pattern QUEST_MARK = Pattern.compile("%3F", Pattern.LITERAL);
private static final Pattern EQUAL = Pattern.compile("%3D", Pattern.LITERAL);
private static final Pattern AMP = Pattern.compile("%26", Pattern.LITERAL);

public static String encodeUrl(String url) {
    if (checkForExternal(url)) {
        try {
            String value = URLEncoder.encode(url, "UTF-8");
            value = COLON.matcher(value).replaceAll(":");
            value = SLASH.matcher(value).replaceAll("/");
            value = QUEST_MARK.matcher(value).replaceAll("?");
            value = EQUAL.matcher(value).replaceAll("=");
            return AMP.matcher(value).replaceAll("&");
        } catch (UnsupportedEncodingException e) {
            throw LOGGER.getIllegalStateException(e);
        }
    } else {
        return url;
    }
}
0 голосов
/ 14 ноября 2017

Замените пробелы в URL на +, как если URL-адрес содержит измерение1 = недержание мочи, затем замените его на измерение1 = недержание мочи.

0 голосов
/ 11 октября 2016

Если вы используете RestangularV2 для публикации на контроллере пружины в Java, вы можете получить это исключение, если вы используете RestangularV2.one() вместо RestangularV2.all()

0 голосов
/ 20 марта 2015

У меня было это исключение в случае теста для проверки некоторых реальных URL-адресов пользователей.

А URL-адреса иногда содержат недопустимый символ и зависают от этой ошибки.

Поэтому я создаю функцию для кодирования только символов в строке URL, как это.

String encodeIllegalChar(String uriStr,String enc)
  throws URISyntaxException,UnsupportedEncodingException {
  String _uriStr = uriStr;
  int retryCount = 17;
  while(true){
     try{
       new URI(_uriStr);
       break;
     }catch(URISyntaxException e){
       String reason = e.getReason();
       if(reason == null ||
         !(
          reason.contains("in path") ||
          reason.contains("in query") ||
          reason.contains("in fragment")
         )
       ){
         throw e;
       }
       if(0 > retryCount--){
         throw e;
       }
       String input = e.getInput();
       int idx = e.getIndex();
       String illChar = String.valueOf(input.charAt(idx));
       _uriStr = input.replace(illChar,URLEncoder.encode(illChar,enc));
     }
  }
  return _uriStr;
}

тест:

String q =  "\\'|&`^\"<>)(}{][";
String url = "http://test.com/?q=" + q + "#" + q;
String eic = encodeIllegalChar(url,'UTF-8');
System.out.println(String.format("  original:%s",url));
System.out.println(String.format("   encoded:%s",eic));
System.out.println(String.format("   uri-obj:%s",new URI(eic)));
System.out.println(String.format("re-decoded:%s",URLDecoder.decode(eic)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...