web-dev-qa-db-fra.com

Comment gérer l'URISyntaxException

J'ai eu ce message d'erreur:

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

Lorsque je l'ai copié dans un champ d'adresse du navigateur, la page correcte a été affichée. Il s'agit d'une URL valide, mais je ne peux pas l'analyser avec ceci: new URI(My_Url)

J'ai essayé: My_Url=My_Url.replace("^","\\^"), mais 

  1. Ce ne sera pas l'URL dont j'ai besoin
  2. Ça ne marche pas non plus

Comment gérer ça?

Franc

36
Frank

Utilisez l'encodage % pour le caractère ^, à savoir. http://finance.yahoo.com/q/h?s=%5EIXIC

17
araqnid

Vous devez encoder l'URI pour remplacer les caractères illégaux par des caractères encodés légaux. Si vous créez d'abord une URL (vous n'avez donc pas à analyser vous-même), puis créez un URI à l'aide du constructeur à cinq arguments , le constructeur effectuera alors l'encodage à votre place. 

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");
    }
  }
}
54
Eddie

Vous devez encoder vos paramètres.

Quelque chose comme ça va faire:

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

14
OscarRyz

Plutôt que d’encoder l’URL auparavant, vous pouvez effectuer les opérations suivantes:

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();
4
Wil Hester

Une solution générale nécessite l'analyse de l'URL dans un URI conforme à RFC 2396 (notez qu'il s'agit d'une ancienne version de la norme URI utilisée par Java.net.URI).

J'ai écrit une bibliothèque d'analyse URL Java qui rend cela possible: galimatias . Avec cette bibliothèque, vous pouvez obtenir le comportement souhaité avec ce code:

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

Notez que galimatias est à un stade très précoce et que certaines fonctionnalités sont expérimentales, mais qu’il est déjà assez solide pour ce cas d’utilisation.

1
smola

Je ne peux rien imaginer de mieux pour 
http://server.ru:8080/template/get?type=mail&format=html&key=ecm_task_assignment&label = Согласовать с контрагентом & descr = Описание & objectid =.
cette:

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;
    }
}
1
GKislin

J'ai eu cette exception dans le cas d'un test pour vérifier certaines URL réellement accédés par les utilisateurs.

Et les URL contiennent parfois un caractère illégal et sont bloquées par cette erreur.

Je crée donc une fonction pour encoder uniquement les caractères de la chaîne d'URL, comme ceci. 

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;
}

tester:

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)));
0
Ayabe Hidetoshi

Remplacez les espaces de l'URL par + like Si l'URL contient dimension1 = doublures d'incontinence, remplacez-la par dimension1 = incontinence + doublures.

0
kkashyap1707

Si vous utilisez RestangularV2 pour publier sur un contrôleur Spring en Java, vous pouvez obtenir cette exception si vous utilisez RestangularV2.one() au lieu de RestangularV2.all().

0
gary69