如何处理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 ,但是我不能用这个parsing它: new URI(My_Url)

我试过了: My_Url=My_Url.replace("^","\\^") ,但

  1. 这不会是我需要的url
  2. 它也不起作用

如何处理这个?

坦率

使用%编码^字符,即。 http://finance.yahoo.com/q/h?s=%5EIXIC

您需要对URI进行编码,以用合法编码的字符replace非法字符。 如果你第一次创build一个URL(所以你不必自己parsing),然后使用五个参数的构造函数来创build一个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; } } 

一般的解决scheme需要将URLparsing为符合RFC 2396的URI(请注意,这是URI标准的旧版本,即java.net.URI使用的)。

我写了一个Java URLparsing库,使这成为可能: galimatias 。 有了这个库,你可以用这个代码实现你想要的行为:

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

请注意,galimatias处于一个非常早期的阶段,有些function是实验性的,但对于这种使用情况已经非常稳固。

在用户检查一些实际访问的URL的testing中,我有这个例外。

而且这个URL有时候会包含一个非法字符,并且被这个错误挂起。

所以我做了一个函数来只编码这个URLstring中的字符。

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

testing:

 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在java中发布到spring控制器,如果使用RestangularV2.one()而不是RestangularV2.all()则可以获得此exception。

用URLreplaceURL中的空格如果url包含dimension1 =失禁内衬,则将其replace为dimension1 =失禁+内衬。