Java WebDriver getCurrentUrl()返回格式错误的URI

Java WebDriver getCurrentUrl()返回格式错误的URI,java,selenium-webdriver,uri,url-encoding,selenium-firefoxdriver,Java,Selenium Webdriver,Uri,Url Encoding,Selenium Firefoxdriver,我参与了用Selenium 2和FireFox驱动程序编写(Java/Groovy)浏览器自动化应用程序的工作 目前,我们在野外发现的一些URL存在一个问题,它们显然使用了错误的URI语法。(特别是大括号({})、|和^) 尝试从驱动程序返回的字符串构造java.net.URI时,会抛出urisyntaxeption new URI(url); // java.net.URISyntaxException: Illegal character in query at index ... 在构建

我参与了用Selenium 2和FireFox驱动程序编写(Java/Groovy)浏览器自动化应用程序的工作

目前,我们在野外发现的一些URL存在一个问题,它们显然使用了错误的URI语法。(特别是大括号(
{}
)、
|
^

尝试从
驱动程序返回的字符串构造
java.net.URI
时,会抛出
urisyntaxeption

new URI(url); // java.net.URISyntaxException: Illegal character in query at index ...
在构建
URI
之前对整个
url
进行编码将不起作用(据我所知)

整个url是经过编码的,它没有任何我可以以任何正常方式解析的片段。例如,使用此uri安全字符串,
uri
无法知道作为查询字符串param delimeter的
&
与单个qs参数内容中的
%26
(其编码值)之间的差异

String encoded = URLEncoder.encode(url, "UTF-8") // http%3A%2F%2Fexample.com%2Ffoo%3Fkey%3Dval%7Cwith%5E%7Cbad%7Ccharacters
URI uri = new URI(encoded)
URLEncodedUtils.parse(uri, "UTF-8") // []
目前的解决方案是,在构建
URI
之前,运行以下(groovy)代码:

但这似乎是肮脏和错误的

我想我的问题是多方面的:

  • 为什么FirefoxDriver返回字符串而不是URI
  • 为什么这个字符串格式不正确
  • 处理这类事情的最佳做法是什么?
  • getCurrentUrl()从浏览器获取字符串,在将其转换为URL之前,应该对字符串进行URL编码


    请参阅Java中的示例。

    我们可以对查询字符串参数进行部分编码,如注释中所述,它应该可以工作

    另一种方法是使用库:

    输出:

    http://example.com/foo?key=val-with-a-|-in-it
    http://example.com/foo?key=val-with-a-%7C-in-it
    http://example.com/?foo={bar}
    http://example.com/?foo=%7Bbar%7D
    

    这对你有用吗

    import java.net.URI;
    import java.net.URL;
    import java.net.URLEncoder;
    
    
    public class Sample {
    
    public static void main(String[] args) throws UnsupportedEncodingException {
        String urlInString="http://example.com/foo?key=val-with-a-{-in-it";
        String encodedURL=URLEncoder.encode(urlInString, "UTF-8");
    
        URI encodedURI=URI.create(encodedURL);
        System.out.println("Actual URL:"+urlInString);
        System.out.println("Encoded URL:"+encodedURL);
        System.out.println("Encoded URI:"+encodedURI);
    
    }
    
    }
    
    输出:

    http://example.com/foo?key=val-with-a-|-in-it
    http://example.com/foo?key=val-with-a-%7C-in-it
    http://example.com/?foo={bar}
    http://example.com/?foo=%7Bbar%7D
    
    实际URL:http://example.com/foo?key=val-里面有一个-{
    编码的URL:http%3A%2F%2fexame.com%2Ffoo%3Fkey%3Dval-with-a-%7B
    
    编码的URI:http%3A%2F%2F example.com%2Ffoo%3Fkey%3Dval-with-a-%7B

    另一种解决方案是拆分获取的URL,然后使用它们创建所需的URL。这将确保获得URL类的所有功能

    import java.io.UnsupportedEncodingException;
    import java.net.MalformedURLException;
    import java.net.URI;     
    import java.net.URISyntaxException;      
    import java.net.URL;
    
    public class Sample {
    
    public static void main(String[] args) throws UnsupportedEncodingException,
            URISyntaxException, MalformedURLException {
        String uri1 = "http://example.com/foo?key=val-with-a-{-in-it";
    
        String scheme=uri1.split(":")[0];
    
        String authority=uri1.split("//")[1].split("/")[0];
    
        String path=uri1.split("//")[1].split("/")[1].split("\\?")[0];  
    
        String query=uri1.split("\\?")[1];  
    
    
        URI uri = null;
        uri = new URI(scheme, authority, "/"+path, query,null);
    
        URL url = null;
    
        url = uri.toURL();
    
        System.out.println("URI's Query:"+uri.getQuery());
        System.out.println("URL's Query:"+url.getQuery());
    
    }
    
    }
    

    我的理解是,这样做会使
    http://example.com/foo?key=val|在http%3A%2F%2Fexample.com%2Ffoo%3Fkey%3Dval%7Cwith%5E%7Cbad%7Ccharacters
    中使用^坏字符
    ,这不是我要寻找的行为。我将测试这一点,以确定这一点,但我认为URI不会在其构造函数中使用此字符串如果我用这个编码的字符串创建一个
    URI
    ,我就无法解析它或对它做任何事情。我会编辑这个问题以使它更清楚。@ZachL我认为这个答案是正确的,但你应该只对查询字符串的一部分进行编码。在你的问题中,你显示你对整个URL进行了编码,这是不正确的。嗯……w这个答案似乎暗示我应该对整个字符串进行编码,这是错误的。我可能会在
    之后提取整个查询字符串,在
    &
    =
    上拆分它,对这些块进行编码,然后将url重新组合在一起。如果你想将其作为答案写出来(或者@dming想编辑他的答案)如果没有更好的解决方案出现,我会将其标记为正确,并奖励赏金。这不清楚-你真的在URL中有这些坏字符吗?你能添加一个你期望看到的字符串的例子吗?谢谢。由于项目的性质,我无法确认实际的URL是否与WebDriver的不同是报告,我也不能分享太多细节,但
    http://example.com/foo?key=val-其中带有-a-|-的
    表示我们在极少数情况下从
    driver.getCurrentUrl()
    返回的实际内容。我刚刚找到的另一个示例:
    http://example.com?foo={bar}
    未编译(将uri1替换为urlInString),而且URLEncoder.encode(字符串)已弃用,您需要使用URLEncoder.encode(字符串,“UTF-8”)谢谢@sap1ens。根据您的建议更新了代码。代码现在应该可以编译了。这与我在问题中使用
    urlcoder
    的方法有何不同?这看起来完全一样,问题也一样。您的方法
    uriencodeduri=newuri(uri1);
    正在生成错误
    //java.net.URISyntaxException:索引处的查询中的非法字符…
    。但是我使用了
    URI encodedURI=URI.create(encodedURL);
    它给出了我显示的输出。这是您正在寻找的输出吗?这与我使用
    URLEncoder.encode的示例的问题相同(url,“UTF-8”)
    (没有错误发生)。在这种情况下,我无法像我需要的那样分析URI。例如:我需要能够执行
    URI.getQuery()
    ,并检索查询字符串,就像它在野外一样:
    ?key=val-with-a-{-在它里面
    。使用galimatias库,我可以得到它。在你的代码中,它返回
    null
    。当
    http://
    被编码时,它变成
    http%3A%2F%2F
    使得它不能正确地解析为URI。对于查询字符串中的
    &
    =/code>也是如此。添加dep不会太激动这似乎是一个有点模糊的库,但到目前为止,这似乎是最好的解决方案。Rameshwar的答案实际上更好,没有额外的库:)见我对他的回答的评论。简言之,使用这个库他的方法是行不通的。这肯定是一种可能的方法,但比我希望的要严厉一点,我想我会默认使用我原来的帖子中的
    replace
    方法。为了让这段代码起作用,我必须使它更加健壮,以处理可能发生的事情没有路径或查询字符串。
    import java.net.URI;
    import java.net.URL;
    import java.net.URLEncoder;
    
    
    public class Sample {
    
    public static void main(String[] args) throws UnsupportedEncodingException {
        String urlInString="http://example.com/foo?key=val-with-a-{-in-it";
        String encodedURL=URLEncoder.encode(urlInString, "UTF-8");
    
        URI encodedURI=URI.create(encodedURL);
        System.out.println("Actual URL:"+urlInString);
        System.out.println("Encoded URL:"+encodedURL);
        System.out.println("Encoded URI:"+encodedURI);
    
    }
    
    }
    
    import java.io.UnsupportedEncodingException;
    import java.net.MalformedURLException;
    import java.net.URI;     
    import java.net.URISyntaxException;      
    import java.net.URL;
    
    public class Sample {
    
    public static void main(String[] args) throws UnsupportedEncodingException,
            URISyntaxException, MalformedURLException {
        String uri1 = "http://example.com/foo?key=val-with-a-{-in-it";
    
        String scheme=uri1.split(":")[0];
    
        String authority=uri1.split("//")[1].split("/")[0];
    
        String path=uri1.split("//")[1].split("/")[1].split("\\?")[0];  
    
        String query=uri1.split("\\?")[1];  
    
    
        URI uri = null;
        uri = new URI(scheme, authority, "/"+path, query,null);
    
        URL url = null;
    
        url = uri.toURL();
    
        System.out.println("URI's Query:"+uri.getQuery());
        System.out.println("URL's Query:"+url.getQuery());
    
    }
    
    }