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

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

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. Он не работает ни

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

Фрэнк

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

Вам нужно закодировать 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"); } } } 

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

Что-то вроде этого будет делать:

 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

Вместо того, чтобы кодировать 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(); 

Не представляйте себе ничего лучше
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; } } 

Общее решение требует parsingа 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); 

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

У меня было это исключение в случае теста для проверки некоторых фактических 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 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))); 

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

Замените пробелы в URL с помощью + like. Если url содержит size1 = Incontinence Liners, замените его с помощью size1 = Incontinence + Liners.

Interesting Posts
Давайте будем гением компьютера.