HostnameVerifier 和 DefaultHostnameVerifier 之间的区别

Difference between HostnameVerifier and DefaultHostnameVerifier

我正在为我的 SSL 客户端实施主机名验证程序。我知道 HTTPS URL 连接的默认主机名验证器是静态的。我的问题是我不希望主机名验证是静态的,因为我的客户端中有多个线程同时访问这个主机名验证器。

目前我的代码如下所示:

我有一个内部 class 用于主机名验证,

public class CreateHostnameVerifier implements HostnameVerifier {
    @Override
    public boolean verify(String hostname, SSLSession session) {

            try {
                if (mInstance.getHost().equals(InetAddress.getByName(hostname)))
                    return true;
                else if (hostname.equals(mInstance.getHost().getHostAddress()))
                    return true;
                else if (hostname.equals(mInstance.getHost().getCanonicalHostName()))
                    return true;
                else
                    return false;

            } catch (UnknownHostException e) {
                System.out.println("Unknown Host");
            }
            return false;
        } 
    }
}

我在构建端点时将其称为 class,

address = mInstance.getSecureConnectionEndpoint();
try {
        HttpsURLConnection Connection = (HttpsURLConnection) address.openConnection();
        CreateHostnameVerifier hv = new CreateHostnameVerifier();
        Connection.setDefaultHostnameVerifier(hv);
        } catch (IOException e1) {
        e1.printStackTrace();
        }

因为我使用 setDefaultHostnameVerifer 并尝试通过 Connection.setDefaultHostnameVerifier 以非静态方式访问它,所以我收到如下警告:

The static method setDefaultHostnameVerifier(HostnameVerifier) from the type HttpsURLConnection should be accessed in a static way

但这绝对可以正常工作,但以防万一我尝试以非静态方式访问它:

Connection.setHostnameVerifier(hv);

它不起作用。 谁能给我解释一下两者之间的区别,即 setHostnameVerifersetDefaultHostnameVerifier

My problem is that I do not want the hostname verification to be static because I have multiple threads in my client accessing this hostname verifier at the same time.

这个“要求”是基于误解。

使用同一个 HostnameVerifier 的多个线程 本身 没有任何问题。除非你做一些非常奇怪的事情,否则这些对象之一应该没有可变状态。如果您的共享对象 HostnameVerifier 实例已安全发布(并且不可变),它可以被多个线程安全地使用而无需同步。


Can someone explain me the difference between the two, i.e., setHostnameVerifier and setDefaultHostnameVerifier.

HttpsURLConnection.setHostnameVerifier 的 javadoc 对此进行了解释:

public void setHostnameVerifier(HostnameVerifier v)

Sets the HostnameVerifier for this instance. New instances of this class inherit the default static hostname verifier set by setDefaultHostnameVerifier. Calls to this method replace this object's HostnameVerifier.

setHostnameVerifier 对您不起作用的一个可能原因可能是您调用它的时间太晚了;即建立连接后,并执行验证。


避免警告的方法是像这样设置默认验证器:

    HttpsURLConnection.setDefaultHostnameVerifier(hv);

它是一个静态方法,因此 应该 通过 class 名称而不是实例引用来调用它。 (这就是警告告诉你的......)