【问题标题】:How to deal with the URISyntaxException如何处理 URISyntaxException
【发布时间】:2010-10-19 11:32:04
【问题描述】:

我收到此错误消息:

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. 这不是我需要的网址
  2. 也不行

如何处理?

弗兰克

【问题讨论】:

    标签: java uri


    【解决方案1】:

    您可以执行以下操作,而不是预先对 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();
    

    【讨论】:

      【解决方案2】:

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

      使用番石榴:

      dependencies {
           compile 'com.google.guava:guava:28.1-jre'
      }
      

      您可以使用 UrlEscapers:

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

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

      【讨论】:

        【解决方案3】:

        将 URL 中的空格替换为 + like 如果 url 包含 dimension1=Incontinence Liners,则将其替换为 dimension1=Incontinence+Liners。

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            【解决方案5】:

            在检查用户实际访问的一些 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 =  "\\'|&`^\"<>)(}{][";
            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)));
            

            【讨论】:

              【解决方案6】:

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

              【讨论】:

                【解决方案7】:

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

                我编写了一个 Java URL 解析库来实现这一点:galimatias。使用此库,您可以使用以下代码实现所需的行为:

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

                请注意,galimatias 处于非常早期的阶段,一些功能是实验性的,但对于这个用例来说已经相当可靠了。

                【讨论】:

                  【解决方案8】:

                  没有比这更好的了
                  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;
                      }
                  }
                  

                  【讨论】:

                    【解决方案9】:

                    您需要对 URI 进行编码以将非法字符替换为合法编码字符。如果您首先创建一个 URL(因此您不必自己进行解析),然后使用 five-argument constructor 创建一个 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");
                        }
                      }
                    }
                    

                    【讨论】:

                    • 如果您以后想将该 URI 转换回 URL,请确保使用 URLDecoder,例如new FileInputStream(URLDecoder.decode(uri.toURL().getFile(), "UTF-8"))
                    • 尝试了多种其他建议的解决方案,这似乎可以解决问题。您可以直接在“new HttpGet(uri)”中使用“uri”。
                    • 帮帮我@@@@@@@@@@@ >>>>>>>>>>>>>>>>
                    • 为什么 nullFragment 必须是一个变量?我们可以在 URI 本身的构造函数中为 null 对吗?这与设计有关吗? @edd
                    • 在任何 # 锚点或非默认端口之后保留内容: URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort( ), url.getPath(), url.getQuery(), url.getRef());
                    【解决方案10】:

                    您必须对参数进行编码。

                    这样就可以了:

                    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

                    【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-10-09
                    • 2018-05-22
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多