如何处理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("^","\\^")
,但
- 这不会是我需要的url
- 它也不起作用
如何处理这个?
坦率
使用%
编码^
字符,即。 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 =失禁+内衬。