HostnameVerifier与DefaultHostnameVerifier

时间:2015-09-21 11:20:28

标签: java ssl jax-ws httpsurlconnection

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

目前我的代码看起来像这样:

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

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;
        } 
    }
}

我在构建端点时调用此类,

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

1 个答案:

答案 0 :(得分:2)

  

我的问题是我不希望主机名验证是静态的,因为我的客户端中有多个线程同时访问此主机名验证器。

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

使用相同HostnameVerifier的多个线程没有本身错误。除非你做一些非常奇怪的事情,否则其中一个对象应该没有可变状态。如果您的共享对象HostnameVerifier实例是安全发布的(并且是不可变的),则可以安全地使用多个线程而无需同步。

  

有人可以向我解释两者之间的区别,即setHostnameVerifiersetDefaultHostnameVerifier

HttpsURLConnection.setHostnameVerifier的javadoc解释了它:

  

public void setHostnameVerifier(HostnameVerifier v)

     

为此实例设置HostnameVerifier。此类的新实例继承由setDefaultHostnameVerifier设置的默认静态主机名验证程序。调用此方法会替换此对象的HostnameVerifier

setHostnameVerifier不适合你的一个可能原因可能是你称之为太晚了;即在建立连接之后,已经进行了验证。

避免警告的方法是设置默认验证程序,如下所示:

    HttpsURLConnection.setDefaultHostnameVerifier(hv);

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