Bing Azure搜索API

我正在尝试连接到Bing搜索API并且无法使代码生效。 我搜索了问题,找不到工作代码。

这是我的代码:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import org.apache.commons.codec.binary.Base64; public class BSearch{ public static void main(String[] args) { // TODO Auto-generated method stub //--------------------------------------Bing search------------------------------ String searchText = "barack"; searchText = searchText.replaceAll(" ", "%20"); String accountKey="MYACCOUNTKEY"; byte[] accountKeyBytes = Base64.encodeBase64((accountKey + ":" + accountKey).getBytes()); String accountKeyEnc = new String(accountKeyBytes); URL url; try { url = new URL( "https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/Web?Query=%27" + searchText + "%27&$top=50&$format=json"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Authorization", "Basic " + accountKeyEnc); // conn.setRequestProperty("Accept", "application/json"); BufferedReader br = new BufferedReader(new InputStreamReader( (conn.getInputStream()))); StringBuilder sb = new StringBuilder(); String output; System.out.println("Output from Server .... \n"); while ((output = br.readLine()) != null) { sb.append(output); System.out.println(output); } conn.disconnect(); } catch (MalformedURLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 

这会导致以下错误:

 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1299) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254) at BSearch.main(BSearch.java:30) Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323) ... 12 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) ... 18 more 

谢谢。

您的Java客户端需要Bing的服务器公共证书来启动通信( SSLHandshake ),您收到错误,因为Bing的证书不在您的默认Java密钥库中作为可信证书。

您可以执行以下操作:

  • 获取Bing的证书并使用keytool导入可信证书的默认Java Keystore,名为cacerts的默认Keystore通常位于JAVA_HOME\jre\lib\security\

keytool -importcert -file bingcertificate.cer -keystore cacerts -alias“bingAlias”

  • 创建一个虚拟SSLSocketFactory以获取SSLContext ,该SSLContext接受任何证书并将其与您的http连接对象一起使用。

工厂示例

 public class DummySSLSocketFactory extends SSLSocketFactory { SSLContext sslContext = SSLContext.getInstance("TLS"); public DummySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { super(truststore); TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // } public X509Certificate[] getAcceptedIssuers() { return null; } }; sslContext.init(null, new TrustManager[] { tm }, null); } @Override public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); } @Override public Socket createSocket() throws IOException { return sslContext.getSocketFactory().createSocket(); } } 

接着

 HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); conn.setSSLSocketFactory(new DummySSLSocketFactory()); 
  • 创建自己的密钥库,导入证书并将其加载到代码中以获得新工厂

密钥库示例:

 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keystore.load(new FileInputStream(new File("keystoreCompletePath")), "passwdKeyStore"); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(keyStore); SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(null, tmf.getTrustManagers(), null); SSLSocketFactory sslFactory = ctx.getSocketFactory(); 

接着

 HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); conn.setSSLSocketFactory(sslFactory); 
Interesting Posts