Come gestire l’URISyntaxException

Ho ricevuto questo messaggio di errore:

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

Quando l’ho copiato in un campo indirizzo del browser, ha mostrato la pagina corretta, è un URL valido, ma non posso analizzarlo con questo: new URI(My_Url)

Ho provato: My_Url=My_Url.replace("^","\\^") , ma

  1. Non sarà l’url di cui ho bisogno
  2. Neanche funziona

Come gestirlo?

Franco

Usa % codifica per il carattere ^ , vale a dire. http://finance.yahoo.com/q/h?s=%5EIXIC

È necessario codificare l’URI per sostituire i caratteri non validi con i caratteri codificati legali. Se prima crei un URL (quindi non devi eseguire l’analisi da solo) e poi fai un URI usando il costruttore di cinque argomenti , il costruttore eseguirà la codifica per te.

 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 (MalformsdURLException e) { System.out.println("URL " + myURL + " is a malformsd URL"); } catch (URISyntaxException e) { System.out.println("URI " + myURL + " is a malformsd URL"); } } } 

Devi codificare i tuoi parametri.

Qualcosa come questo farà:

 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

Piuttosto che codificare l’URL prima di mano puoi fare quanto segue

 String link = "http://foo.com"; URL url = null; URI uri = null; try { url = new URL(link); } catch(MalformsdURLException 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(); 

Non immagina niente di meglio per
http://server.ru:8080/template/get?type=mail&format=html&key=ecm_task_assignment&label = Согласовать с контрагентом & descr = Описание & objectid = 2231
quella:

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

Una soluzione generale richiede l’analisi dell’URL in un URI conforms a RFC 2396 (si noti che questa è una vecchia versione dello standard URI, che utilizza java.net.URI).

Ho scritto una libreria di analisi degli URL Java che rende ansible ciò: galimatias . Con questa libreria, puoi ottenere il tuo comportamento desiderato con questo codice:

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

Nota che le galimazie sono in una fase molto precoce e alcune funzionalità sono sperimentali, ma è già abbastanza solida per questo caso d’uso.

Ho avuto questa eccezione nel caso di un test per verificare alcuni URL effettivamente accessibili dagli utenti.

E gli URL qualche volta contengono un carattere illegale e sono bloccati da questo errore.

Quindi creo una funzione per codificare solo i caratteri nella stringa dell’URL come questo.

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

test:

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

Se stai usando RestangularV2 per postare su un controller spring in java puoi ottenere questa eccezione se usi RestangularV2.one() invece di RestangularV2.all()

Sostituisci gli spazi nell’URL con + like If url contiene dimension1 = Incontinence Liners quindi sostituiscilo con dimension1 = Incontinence + Liners.