Cómo lidiar con la excepción URISyntaxException

Recibí este mensaje de error:

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

Cuando lo copié en un campo de dirección del navegador, mostraba la página correcta, es una URL válida, pero no puedo analizarla con esto: new URI(My_Url)

Intenté: My_Url=My_Url.replace("^","\\^") , pero

  1. No será la url que necesito
  2. No funciona tampoco

¿Cómo manejar esto?

Franco

Usa % encoding para el carácter ^ , viz. http://finance.yahoo.com/q/h?s=%5EIXIC

Necesita codificar el URI para reemplazar caracteres ilegales con caracteres codificados legalmente. Si primero hace una URL (por lo que no tiene que hacer el análisis él mismo) y luego hace una URI usando el constructor de cinco argumentos , entonces el constructor hará la encoding por usted.

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

Tienes que codificar tus parámetros.

Algo como esto hará:

 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

En lugar de codificar la URL de antemano, puede hacer lo siguiente

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

No se imagine nada mejor para
http://server.ru:8080/template/get?type=mail&format=html&key=ecm_task_assignment&label = Согласовать с контрагентом & descr = Описание & objectid = 2231
ese:

 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 solución general requiere analizar la URL en un URI compatible con RFC 2396 (tenga en cuenta que esta es una versión anterior del estándar URI, que java.net.URI utiliza).

He escrito una biblioteca de análisis de URL Java que hace esto posible: galimatias . Con esta biblioteca, puede lograr su comportamiento deseado con este código:

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

Tenga en cuenta que las galimatias se encuentran en una etapa muy inicial y algunas características son experimentales, pero ya es bastante sólido para este caso de uso.

Tuve esta excepción en el caso de una prueba para verificar algunas URL reales accedidas por los usuarios.

Y las URL alguna vez contienen un carácter ilegal y se cuelgan por este error.

Así que hago una función para codificar solo los caracteres en la cadena de URL como esta.

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

prueba:

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

Si está utilizando RestangularV2 para publicar en un controlador de spring en java, puede obtener esta excepción si usa RestangularV2.one() lugar de RestangularV2.all()

Reemplazar espacios en URL con + como If url contiene dimension1 = Incontinence Liners y luego reemplazarlo con dimension1 = Incontinence + Liners.