Java 如何处理URISyntaxException

Java 如何处理URISyntaxException,java,uri,Java,Uri,我收到了以下错误消息: 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,但我无法用以下内容解析它:新URI(我的URL) 我试过:My\u Url=My\u Url.rep

我收到了以下错误消息:

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
,但我无法用以下内容解析它:
新URI(我的URL)

我试过:
My\u Url=My\u Url.replace(“^”,“\\^”)
,但是

  • 这将不是我需要的url
  • 它也不起作用
  • 如何处理


    Frank

    使用
    %
    编码
    ^
    字符,即<代码>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 );
    
        }
    }
    

    没有比这更好的了
    =Сааааааааааааааааааа
    即:

    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;
        }
    }
    
    publicstaticbooleanchcheckforexternal(stringstr){
    int length=str.length();
    for(int i=0;i0x7F){
    返回true;
    }
    }
    返回false;
    }
    私有静态最终模式冒号=Pattern.compile(“%3A”,Pattern.LITERAL);
    私有静态最终模式斜杠=Pattern.compile(“%2F”,Pattern.LITERAL);
    私有静态最终模式QUEST_MARK=Pattern.compile(“%3F”,Pattern.LITERAL);
    私有静态最终模式EQUAL=Pattern.compile(“%3D”,Pattern.LITERAL);
    私有静态最终模式AMP=Pattern.compile(“%26”,Pattern.LITERAL);
    公共静态字符串编码url(字符串url){
    如果(检查外部(url)){
    试一试{
    字符串值=URLEncoder.encode(url,“UTF-8”);
    value=COLON.matcher(value.replaceAll(“:”);
    value=SLASH.matcher(value.replaceAll(“/”);
    value=QUEST\u MARK.matcher(value).replaceAll(“?”);
    value=EQUAL.matcher(value).replaceAll(“=”);
    返回AMP.matcher(值).replaceAll(&);
    }捕获(不支持的编码异常e){
    抛出LOGGER.getIllegalStateException(e);
    }
    }否则{
    返回url;
    }
    }
    
    一般解决方案需要将URL解析为符合RFC 2396的URI(请注意,这是java.net.URI使用的URI标准的旧版本)

    我已经编写了一个Java URL解析库,使之成为可能:。使用此库,您可以通过以下代码实现所需的行为:

    String urlString=/。。。
    URLParsingSettings settings=URLParsingSettings.create()
    .耐受标准(URLParsingSettings.Standard.RFC_2396);
    URL=URL.parse(设置,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;
    }
    
    测试:

    String q=“\\'”和“^\”(}{][”;
    字符串url=”http://test.com/?q=“+q+”#“+q;
    字符串eic=encodeIllegalChar(url,'UTF-8');
    System.out.println(String.format(“原始:%s”,url));
    System.out.println(String.format(“编码的:%s”,eic));
    System.out.println(String.format(“uri对象:%s”,新uri(eic));
    System.out.println(String.format(“重新解码:%s”,URLDecode.decode(eic));
    
    您可以执行以下操作,而不是事先对URL进行编码

    String link = "http://example.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();
    

    如果您使用
    RestangularV2
    在java中发布到spring控制器,如果您使用
    RestangularV2.one()
    而不是
    RestangularV2.all(),则会出现此异常

    将URL中的空格替换为+,就像URL包含维度1=失禁内衬,然后将其替换为维度1=失禁内衬。

    在URL中,空格编码为%20,在表单提交的数据(内容类型应用程序/x-www-form-urlencoded)中,空格编码为+。您需要前者

    使用番石榴:

    dependencies {
         compile 'com.google.guava:guava:28.1-jre'
    }
    
    您可以使用URL转义符:

    String encodedString = UrlEscapers.urlFragmentEscaper().escape(inputString);
    

    不要使用String.replace,这只会对空间进行编码。请改用库。

    如果以后要将该URI转换回URL,请确保使用URLDecover,例如
    新文件输入流(URLDecord.decode(URI.toURL().getFile(),“UTF-8”))
    尝试了多个其他建议的解决方案,这似乎奏效了。您可以直接在“新HttpGet(uri)”中使用“uri”“.请帮我一个忙:@@@@@@@@@@@>>>>>>>>>>>>>>>>>>>>>>>>>为什么nullFragment必须是一个变量?我们可以在URI本身的构造函数中为null,对吗?这与设计有关吗?@EDD要在任何#锚定或非默认端口之后保留内容,请执行以下操作:URI URI URI=新URI(url.getProtocol(),url.getUserInfo(),url.getHost(),url.getPort(),url.getPath()),url.getQuery(),url.getRef());URLEncoder()不是URI段编码器。这是由URI类本身完成的。URLEncoder是HTML表单的编码器!它是非常接近的匹配项,但不是100%
    String encodedString = UrlEscapers.urlFragmentEscaper().escape(inputString);