Как справиться с 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("^","^")
, а
- это не будет url, который мне нужен
- не работает
как с этим справиться ?
Фрэнк
9 ответов
вам нужно закодировать 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=Согласовать с контрагентом&ОП=Описание&ид_объекта=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;
}
}
общее решение требует синтаксического анализа URL-адреса в совместимый URI RFC 2396 (обратите внимание, что это старая версия стандарта URI, который java.сеть.URI использует).
Я написал библиотеку синтаксического анализа URL Java, которая делает это возможным:galimatias. С помощью этой библиотеки вы можете достичь желаемого поведения с помощью этого кода:
String urlString = //...
URLParsingSettings settings = URLParsingSettings.create()
.withStandard(URLParsingSettings.Standard.RFC_2396);
URL url = URL.parse(settings, urlString);
обратите внимание, что galimatias находится на очень ранней стадии, и некоторые функции являются экспериментальными, но уже довольно прочными для этот вариант использования.
у меня было это исключение в случае теста для проверки некоторых фактических доступных 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;
}
Если вы используете RestangularV2
для публикации на контроллере spring в java вы можете получить это исключение, если используете RestangularV2.one()
вместо RestangularV2.all()
замените пробелы в URL на + like, если url содержит Dimension1=вкладыши недержания, затем замените его на dimension1=вкладыши недержания+.