【问题标题】:Comparing URLs with parameters in Java将 URL 与 Java 中的参数进行比较
【发布时间】:2012-09-19 08:56:28
【问题描述】:

这两个url应该是一样的:

http://localhost?asdf=1&qwer=2
http://localhost?qwer=2&asdf=1

但是使用 URL 类中的“equals()”,我知道它们是不同的。如何比较它们?

编辑:关于这个问题的一些背景

我正在为一些 url 映射创建一个 Selenium 测试。我有旧的 url,它应该映射到的 url 和实际的 url。我需要将应该的 url 与实际的 url 进行比较。 url 列表由客户端创建。如果参数列表相同,并且它们都具有正确的值(这些参数的顺序无关),则具有相同参数和值的 URL 被认为是有效的

【问题讨论】:

  • 这两个 URL 对我来说是不同的(以及对许多其他人来说:)),这就是 URL 类中的 equals 方法为此返回 false 的原因。您应该编写自己的方法来比较查询参数并据此返回结果。
  • 它们实际上是一样的。参数的顺序对任何 J2EE 应用程序都没有影响。

标签: java url selenium


【解决方案1】:

所以,如果我没记错的话,你想比较两个 URL,不管查询部分的顺序如何。

URL 类中似乎没有这种方法,因此您必须自己编写。 此外,URLfinal,您不能覆盖 URL.equals(Object)

您的方法可以从调用sameFile()开始。
如果计算结果为true,则调用getQuery(),并将其拆分为它的组件——可能使用String.split("\&")。从那里开始,您评估参数是否相同。
另外,不要忘记检查“#fragment”是否相等,如果这对您的应用程序很重要。

【讨论】:

    【解决方案2】:

    我不认为你会喜欢它,但你可以做类似的事情

    URL url = new URL("http://localhost?asdf=1&qwer=2");
    URL url2 = new URL("http://localhost?qwer=2&asdf=1");
    
    System.out.println(isEqual(url, url2));
    
    public static boolean isEqual(URL url1, URL url2) {
    
        boolean isEqual = url1.getAuthority().equals(url2.getAuthority()) &&
                        url1.getPort() == url2.getPort() &&
                        url1.getHost().equals(url2.getHost()) &&
                        url1.getProtocol().equals(url2.getProtocol());
    
        if (isEqual) {
    
            String query1 = url1.getQuery();
            String query2 = url2.getQuery();
    
            if (query1 != null && query2 != null) {
    
                if (query1.length() == query2.length()) {
    
                    List<String> list1 = getParameters(query1);
                    List<String> list2 = getParameters(query2);
    
                    for (int index = 0; index < list1.size(); index++) {
    
                        String value1 = list1.get(index);
                        String value2 = list2.get(index);
                        if (!value1.equals(value2)) {
    
                            isEqual = false;
                            break;
    
                        }
    
                    }
    
                } else {
    
                    isEqual = false;
    
                }
    
            } else {
    
                isEqual = false;
    
            }
    
        }
    
        return isEqual;
    
    }
    
    protected static List<String> getParameters(String value) {
    
        List<String> parameters = new ArrayList<String>(25);
    
        String[] values = value.split("&");
        for (String par : values) {
    
            if (!par.contains("=")) {
                par += "=null";
            }
    
            parameters.add(par);
    
        }
    
        Collections.sort(parameters);
    
        return parameters;
    
    }
    

    【讨论】:

      【解决方案3】:

      URL/URI equals 方法已损坏。至少它没有提供您期望的结果。 它有很多奇怪的东西。您可能有兴趣阅读

      Mr. Gosling – why did you make URL equals suck?!?

      或许

      How to compare two URLs in java?

      所以,不要指望这会很容易。 您可以为您的特定情况创建自定义比较器,但通常您可能必须解析 url 字符串。

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        您可以使用 String 类中提供的功能来完成此操作。

        这种方法将 URL 分成两部分,“?”之前的部分和之后的一个(如果没有“?”或参数也可以)。如果“?”之前的 URL是等价的,就我们的目的而言,两者是“等价的”。

        public boolean urlsMatchWithoutQueryParameters(String firstUrl, secondUrl) {
            // Get the portion of the URLs before the "?", and before all parameters.
            String firstUrlWithoutParameters = firstUrl.split("\\?", 2)[0];
            String secondUrlWithoutParameters = secondUrl.split("\\?", 2)[0];
        
            return firstUrlWithoutParameters.equals(secondUrlWithoutParameters);
        }
        

        代码有点拥挤,所以你可以像这样将 String 逻辑拉到一个帮助器中:

        public boolean urlsMatchWithoutQueryParameters(String firstUrl, secondUrl) {
            return getUrlWithoutParameters(firstUrl).equals(getUrlWithoutParameters(secondUrl));
        }
        
        public String getUrlWithoutParameters(String url) {
            // Get the portion of the URL before the "?", and before all parameters.
            return url.split("\\?", 2)[0];
        }
        

        注意:这会忽略 URL 锚点(例如,URL www.example.com/profiles/user123#friends 中的#photos)。
        对于锚点,只需将split("\\?", 2) 中的"#" 替换为"\\?"

        【讨论】:

          【解决方案5】:

          我喜欢这个问题,所以我写了这个小演示。 (对不起,我使用 StringUtils 类作为子字符串)

          import java.net.MalformedURLException;
          import java.net.URL;
          import java.util.Arrays;
          import java.util.List;
          
          import org.apache.commons.lang.StringUtils;
          
          public class URLDemo
          {
          
              /**
               * @param args
               * @throws MalformedURLException
               */
              public static void main(String[] args)
                  throws MalformedURLException
              {
                  String url1 = "http://localhost?asdf=1&qwer=2";
                  String url2 = "http://localhost?qwer=2&asdf=1";
                  URL url11 = new URL(StringUtils.substringBefore(url1, "?"));
                  URL url22 = new URL(StringUtils.substringBefore(url2, "?"));
          
                  if (url11.equals(url22))
                  {
                      // url are equal but still need to check the parameters
                      List<String> params1 = Arrays.asList(StringUtils.split(StringUtils.substringAfter(url1, "?"), "&"));
                      List<String> params2 = Arrays.asList(StringUtils.split(StringUtils.substringAfter(url2, "?"), "&"));
          
                      // need to check both ways
                      if (params1.containsAll(params2) && params2.containsAll(params1))
                      {
                          System.out.println("URLs are the same");
                      }
                      else
                      {
                          System.out.println("URLs are different");
                      }
                  }
              }
          
          }
          

          【讨论】:

          • 我可能不得不做这样的事情。我真的很难相信没有经过测试的库可以进行这样的比较。我总是担心这样的代码将如何处理编码、结束斜杠(“localhost/”与“localhost”)等等。我通常讨厌重新发明轮子....
          【解决方案6】:

          这两个网址实际上是不同的

          http://localhost?asdf=1&qwer=2
          http://localhost?qwer=2&asdf=1
          

          //////// 编辑部分 //////////

          试试这个....

          -both 网址上使用 openStream()

          - 将它们都保存为 2 个String 对象,或者改为StringBuilder

          - 现在使用equals() 比较它们。

          -这会解决问题的,我想是的......

          【讨论】:

          • 注意参数是一样的,只是顺序不同。我认为问题是关于这个的。
          • @S.L.Barth equals() 方法检查对象引用变量指向的对象是相同还是不同,as both the url are different, 2 different objects are created on the heap, so we get that both are diff...as simple as that....
          • @KumarVivekMitra equals 已被覆盖...您没有在此处比较堆地址。
          • 我明白了,但 OP 的问题是(显然)如何查找 URL 是否与参数的顺序相同 。他可能需要编写自己的比较器。
          猜你喜欢
          • 2019-07-26
          • 2014-05-17
          • 1970-01-01
          • 1970-01-01
          • 2021-02-16
          • 2020-07-16
          • 2017-06-10
          • 2016-07-10
          • 1970-01-01
          相关资源
          最近更新 更多