java 访问https 证书_Java的HttpClient如何去支持无证书访问https

展开全部

项目里需要访问其他接口,通过http/https协议。32313133353236313431303231363533e58685e5aeb931333337373634我们一般是用HttpClient类来实现具体的http/https协议接口的调用。

// Init a HttpClient

HttpClient client = new HttpClient();

String url=http://www.xxx.com/xxx;

// Init a HttpMethod

HttpMethod get = new GetMethod(url);

get.setDoAuthentication(true);

get.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(1, false));

// Call http interface

try {

client.executeMethod(get);

// Handle the response from http interface

InputStream in = get.getResponseBodyAsStream();

SAXReader reader = new SAXReader();

Document doc = reader.read(in);

} finally {

// Release the http connection

get.releaseConnection();

}

以上代码在通过普通的http协议是没有问题的,但如果是https协议的话,就会有证书文件的要求了。一般情况下,是这样去做的。

// Init a HttpClient

HttpClient client = new HttpClient();

String url=https://www.xxx.com/xxx;

if (url.startsWith("https:")) {

System.setProperty("javax.net.ssl.trustStore", "/.sis.cer");

System.setProperty("javax.net.ssl.trustStorePassword", "public");

}

于是,这里就需要事先生成一个.sis.cer的文件,生成这个文件的方法一般是先通过浏览器访问https://,导出证书文件,再用JAVA keytool command 生成证书

# $JAVA_HOME/bin/keytool -import -file sis.cer -keystore .sis.cer

但这样做,一比较麻烦,二来证书也有有效期,过了有效期之后,又需要重新生成一次证书。如果能够避开生成证书文件的方式来使用https的话,就比较好了。

还好,在最近的项目里,我们终于找到了方法。

// Init a HttpClient

HttpClient client = new HttpClient();

String url=https://www.xxx.com/xxx;

if (url.startsWith("https:")) {

this.supportSSL(url, client);

}

用到了supportSSL(url, client)这个方法,看看这个方法是如何实现的。

private void supportSSL(String url, HttpClient client) {

if(StringUtils.isBlank(url)) {

return;

}

String siteUrl = StringUtils.lowerCase(url);

if (!(siteUrl.startsWith("https"))) {

return;

}

try {

setSSLProtocol(siteUrl, client);

} catch (Exception e) {

logger.error("setProtocol error ", e);

}

Security.setProperty( "ssl.SocketFactory.provider",

"com.tool.util.DummySSLSocketFactory");

}

private static void setSSLProtocol(String strUrl, HttpClient client) throws Exception {

URL url = new URL(strUrl);

String host = url.getHost();

int port = url.getPort();

if (port <= 0) {

port = 443;

}

ProtocolSocketFactory factory = new SSLSocketFactory();

Protocol authhttps = new Protocol("https", factory, port);

Protocol.registerProtocol("https", authhttps);

// set https protocol

client.getHostConfiguration().setHost(host, port, authhttps);

}

在supportSSL方法里,调用了Security.setProperty( "ssl.SocketFactory.provider",

"com.tool.util.DummySSLSocketFactory");

那么这个com.tool.util.DummySSLSocketFactory是这样的:

访问https 资源时,让httpclient接受所有ssl证书,在weblogic等容器中很有用

代码如下:

1. import java.io.IOException;

2. import java.net.InetAddress;

3. import java.net.InetSocketAddress;

4. import java.net.Socket;

5. import java.net.SocketAddress;

6. import java.net.UnknownHostException;

7. import java.security.KeyManagementException;

8. import java.security.NoSuchAlgorithmException;

9. import java.security.cert.CertificateException;

10. import java.security.cert.X509Certificate;

11.

12. import javax.net.SocketFactory;

13. import javax.net.ssl.SSLContext;

14. import javax.net.ssl.TrustManager;

15. import javax.net.ssl.X509TrustManager;

16.

17. import org.apache.commons.httpclient.ConnectTimeoutException;

18. import org.apache.commons.httpclient.params.HttpConnectionParams;

19. import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;

20.

21. public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {

22. static{

23. System.out.println(">>>>in MySecureProtocolSocketFactory>>");

24. }

25. private SSLContext sslcontext = null;

26.

27. private SSLContext createSSLContext() {

28. SSLContext sslcontext=null;

29. try {

30. sslcontext = SSLContext.getInstance("SSL");

31. sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());

32. } catch (NoSuchAlgorithmException e) {

33. e.printStackTrace();

34. } catch (KeyManagementException e) {

35. e.printStackTrace();

36. }

37. return sslcontext;

38. }

39.

40. private SSLContext getSSLContext() {

41. if (this.sslcontext == null) {

42. this.sslcontext = createSSLContext();

43. }

44. return this.sslcontext;

45. }

46.

47. public Socket createSocket(Socket socket, String host, int port, boolean autoClose)

48. throws IOException, UnknownHostException {

49. return getSSLContext().getSocketFactory().createSocket(

50. socket,

51. host,

52. port,

53. autoClose

54. );

55. }

56.

57. public Socket createSocket(String host, int port) throws IOException,

58. UnknownHostException {

59. return getSSLContext().getSocketFactory().createSocket(

60. host,

61. port

62. );

63. }

64.

65.

66. public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)

67. throws IOException, UnknownHostException {

68. return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);

69. }

70.

71. public Socket createSocket(String host, int port, InetAddress localAddress,

72. int localPort, HttpConnectionParams params) throws IOException,

73. UnknownHostException, ConnectTimeoutException {

74. if (params == null) {

75. throw new IllegalArgumentException("Parameters may not be null");

76. }

77. int timeout = params.getConnectionTimeout();

78. SocketFactory socketfactory = getSSLContext().getSocketFactory();

79. if (timeout == 0) {

80. return socketfactory.createSocket(host, port, localAddress, localPort);

81. } else {

82. Socket socket = socketfactory.createSocket();

83. SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);

84. SocketAddress remoteaddr = new InetSocketAddress(host, port);

85. socket.bind(localaddr);

86. socket.connect(remoteaddr, timeout);

87. return socket;

88. }

89. }

90.

91. //自定义私有类

92. private static class TrustAnyTrustManager implements X509TrustManager {

93.

94. public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

95. }

96.

97. public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

98. }

99.

100. public X509Certificate[] getAcceptedIssuers() {

101. return new X509Certificate[]{};

102. }

103. }

104.

105. }

public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {

static{

System.out.println(">>>>in MySecureProtocolSocketFactory>>");

}

private SSLContext sslcontext = null;

private SSLContext createSSLContext() {

SSLContext sslcontext=null;

try {

sslcontext = SSLContext.getInstance("SSL");

sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (KeyManagementException e) {

e.printStackTrace();

}

return sslcontext;

}

private SSLContext getSSLContext() {

if (this.sslcontext == null) {

this.sslcontext = createSSLContext();

}

return this.sslcontext;

}

public Socket createSocket(Socket socket, String host, int port, boolean autoClose)

throws IOException, UnknownHostException {

return getSSLContext().getSocketFactory().createSocket(

socket,

host,

port,

autoClose

);

}

public Socket createSocket(String host, int port) throws IOException,

UnknownHostException {

return getSSLContext().getSocketFactory().createSocket(

host,

port

然后按如下方式使用HttpClient

Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443);

Protocol.registerProtocol("https", myhttps);

HttpClient httpclient=new HttpClient();

2Q==

已赞过

已踩过<

你对这个回答的评价是?

评论

收起

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值