Here's a simple problem - given two urls, is there some built-in method, or an Apache library that decides whether they are (logically) equal?
For example, these two urls are equal:
http://stackoverflow.com http://stackoverflow.com/ While URI.equals() (as well as the problematic URL.equals()) does not return true for these specific examples, I think it's the only case where equivalence can be assumed (because there is no empty path in the HTTP protocol).
The URIs http://stackoverflow.com/foo and http://stackoverflow.com/foo/ can not be assumed to be equivalent.
Maybe you can use URI.equals() wrapped in a utility method that handles this specific case explicitly.
sameFile() documentation that implies that the port defaults are handled by that (and a quick test doesn't support that assumption). Additionally sameFile() suffers from the same problem as URL.equals(), as it also tries to resolve the host name.http://foo.googlecode.com/ and http://bar.googlecode.com/ for example).URL urlOne = new URL("http://stackoverflow.com"); URL urlTwo = new URL("http://stackoverflow.com/"); if( urlOne.equals(urlTwo) ) { // .... } Note from docs -
Two URL objects are equal if they have the same protocol, reference equivalent hosts, have the same port number on the host, and the same file and fragment of the file.
Two hosts are considered equivalent if both host names can be resolved into the same IP addresses; else if either host name can't be resolved, the host names must be equal without regard to case; or both host names equal to null.
Since hosts comparison requires name resolution, this operation is a blocking operation.
Note: The defined behavior for equals is known to be inconsistent with virtual hosting in HTTP.
So, instead you should prefer URI::equals reference as @Joachim suggested.
URL.equals() will resolve the host names! Not only does this introduce Network IO at places where it's not expected, but it will also produce wrong results (i.e. http://vhost1.com/ will be equal to http://vhost2.com/ if they are hosted at the same IP!). It's better to use URI and call URI.equals().URL.equals() might produce diffrent/inconsistent results depending on whether you have Internet connection or not...The following may work for you - it validates that 2 urls are equal, allows the parameters to be supplied in different orders, and allows a variety of options to be configured, that being:
You can test it like so:
class Main { public static void main(String[] args) { UrlComparer urlComparer = new UrlComparer(); expectResult(false, "key a case different", urlComparer.urlsMatch("//test.com?A=a&B=b", "//test.com?a=a&b=b")); expectResult(false, "key a case different", urlComparer.urlsMatch("https://WWW.TEST.COM?A=1&b=2", "https://www.test.com?b=2&a=1")); expectResult(false, "key a value different", urlComparer.urlsMatch("/test?a=2&A=A", "/test?a=A&a=2")); expectResult(false, "key a value different", urlComparer.urlsMatch("https://WWW.TEST.COM?A=a&b=2", "https://www.test.com?b=2&A=1")); expectResult(false, "null", urlComparer.urlsMatch("/test", null)); expectResult(false, "null", urlComparer.urlsMatch(null, "/test")); expectResult(false, "port different", urlComparer.urlsMatch("//test.com:22?A=a&B=b", "//test.com:443?A=a&B=b")); expectResult(false, "port different", urlComparer.urlsMatch("https://WWW.TEST.COM:8443", "https://www.test.com")); expectResult(false, "protocol different", urlComparer.urlsMatch("http://WWW.TEST.COM:2121", "https://www.test.com:2121")); expectResult(false, "protocol different", urlComparer.urlsMatch("http://WWW.TEST.COM?A=a&b=2", "https://www.test.com?b=2&A=a")); expectResult(true, "both null", urlComparer.urlsMatch(null, null)); expectResult(true, "host and scheme different case", urlComparer.urlsMatch("HTTPS://WWW.TEST.COM", "https://www.test.com")); expectResult(true, "host different case", urlComparer.urlsMatch("https://WWW.TEST.COM:443", "https://www.test.com")); expectResult(true, "identical urls", urlComparer.urlsMatch("//test.com:443?A=a&B=b", "//test.com:443?A=a&B=b")); expectResult(true, "identical urls", urlComparer.urlsMatch("/test?a=A&a=2", "/test?a=A&a=2")); expectResult(true, "identical urls", urlComparer.urlsMatch("https://www.test.com", "https://www.test.com")); expectResult(true, "parameter order changed", urlComparer.urlsMatch("https://www.test.com?a=1&b=2&c=522%2fMe", "https://www.test.com?c=522%2fMe&b=2&a=1")); expectResult(true, "parmeter order changed", urlComparer.urlsMatch("https://WWW.TEST.COM?a=1&b=2", "https://www.test.com?b=2&a=1")); } public static void expectResult(boolean expectedResult, String msg, boolean result) { if (expectedResult != result) throw new RuntimeException(msg); } } UrlComparer.java
import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.TreeMap; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; public class UrlComparer { private boolean hostIsCaseSensitive = false; private boolean pathIsCaseSensitive = true; private boolean queryStringKeysAreCaseSensitive = true; private boolean queryStringValuesAreCaseSensitive = false; private boolean schemeIsCaseSensitive = false; public boolean urlsMatch(String url1, String url2) { try { if (Objects.equals(url1, url2)) return true; URI uri1 = new URI(url1); URI uri2 = new URI(url2); // Compare Query String Parameters Map<String, String> mapParams1 = getQueryStringParams(uri1); Map<String, String> mapParams2 = getQueryStringParams(uri2); if (!mapsAreEqual(mapParams1, mapParams2, getQueryStringValuesAreCaseSensitive())) return false; // Compare scheme (http or https) if (!stringsAreEqual(uri1.getScheme(), uri2.getScheme(), getSchemeIsCaseSensitive())) return false; // Compare host if (!stringsAreEqual(uri1.getHost(), uri2.getHost(), getHostIsCaseSensitive())) return false; // Compare path if (!stringsAreEqual(uri1.getPath(), uri2.getPath(), getPathIsCaseSensitive())) return false; // Compare ports if (!portsAreEqual(uri1, uri2)) return false; return true; } catch (Exception e) { return false; } } protected Map<String, String> getQueryStringParams(URI uri) { Map<String, String> result = getListAsMap(URLEncodedUtils.parse(uri, "UTF-8"), getQueryStringKeysAreCaseSensitive()); return result; } protected boolean stringsAreEqual(String s1, String s2, boolean caseSensitive) { // Eliminate null cases if (s1 == null || s2 == null) { if (s1 == s2) return true; return false; } if (caseSensitive) { return s1.equals(s2); } return s1.equalsIgnoreCase(s2); } protected boolean mapsAreEqual(Map<String, String> map1, Map<String, String> map2, boolean caseSensitiveValues) { for (Map.Entry<String, String> entry : map1.entrySet()) { String key = entry.getKey(); String map1value = entry.getValue(); String map2value = map2.get(key); if (!stringsAreEqual(map1value, map2value, caseSensitiveValues)) return false; } for (Map.Entry<String, String> entry : map2.entrySet()) { String key = entry.getKey(); String map2value = entry.getValue(); String map1value = map2.get(key); if (!stringsAreEqual(map1value, map2value, caseSensitiveValues)) return false; } return true; } protected boolean portsAreEqual(URI uri1, URI uri2) { int port1 = uri1.getPort(); int port2 = uri2.getPort(); if (port1 == port2) return true; if (port1 == -1) { String scheme1 = (uri1.getScheme() == null ? "http" : uri1.getScheme()).toLowerCase(); port1 = scheme1.equals("http") ? 80 : 443; } if (port2 == -1) { String scheme2 = (uri2.getScheme() == null ? "http" : uri2.getScheme()).toLowerCase(); port2 = scheme2.equals("http") ? 80 : 443; } boolean result = (port1 == port2); return result; } protected Map<String, String> getListAsMap(List<NameValuePair> list, boolean caseSensitiveKeys) { Map<String, String> result; if (caseSensitiveKeys) { result = new HashMap<String, String>(); } else { result = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER); } for (NameValuePair param : list) { if (caseSensitiveKeys) { if (!result.containsKey(param.getName())) result.put(param.getName(), param.getValue()); } else { result.put(param.getName(), param.getValue()); } } return result; } public boolean getSchemeIsCaseSensitive() { return schemeIsCaseSensitive; } public void setSchemeIsCaseSensitive(boolean schemeIsCaseSensitive) { this.schemeIsCaseSensitive = schemeIsCaseSensitive; } public boolean getHostIsCaseSensitive() { return hostIsCaseSensitive; } public void setHostIsCaseSensitive(boolean hostIsCaseSensitive) { this.hostIsCaseSensitive = hostIsCaseSensitive; } public boolean getPathIsCaseSensitive() { return pathIsCaseSensitive; } public void setPathIsCaseSensitive(boolean pathIsCaseSensitive) { this.pathIsCaseSensitive = pathIsCaseSensitive; } public boolean getQueryStringKeysAreCaseSensitive() { return queryStringKeysAreCaseSensitive; } public void setQueryStringKeysAreCaseSensitive(boolean queryStringKeysAreCaseSensitive) { this.queryStringKeysAreCaseSensitive = queryStringKeysAreCaseSensitive; } public boolean getQueryStringValuesAreCaseSensitive() { return queryStringValuesAreCaseSensitive; } public void setQueryStringValuesAreCaseSensitive(boolean queryStringValuesAreCaseSensitive) { this.queryStringValuesAreCaseSensitive = queryStringValuesAreCaseSensitive; } } sameFile
public boolean sameFile(URL other)Compares two URLs,
excluding the fragment component. Returns true if this URL and the other argument are equal without taking the fragment component into consideration.
Parameters: other - the URL to compare against. Returns: true if they reference the same remote object; false otherwise.
also please go through this link
http://download.oracle.com/javase/6/docs/api/java/net/URL.html#sameFile(java.net.URL)
As iam unable to add comment , browser throwing Javascript error. so iam adding my comment here. regret for inconvience.
//this what i suggeted
>URL url1 = new URL("http://stackoverflow.com/foo"); >URL url2 = new URL("http://stackoverflow.com/foo/"); >System.out.println(url1.sameFile(url2)); // this is suggested by Joachim Sauer >URI uri = new URI("http://stackoverflow.com/foo/"); >System.out.println(uri.equals("http://stackoverflow.com/foo")); // Both are giving same result so Joachim Sauer check once.
false.