2013-12-20 162 views
1

我正尝试连接到Bing搜索api,并且无法获取代码才能工作。我搜索了这个问题,没有找到工作代码。Bing Azure搜索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 

谢谢。

+0

你见过什么样子了同样的问题:http://stackoverflow.com/questions/9619030/resolving-javax-net- SSL-出现SSLHandshakeException - 太阳安全验证,validatore – Bobulous

回答

6

您的Java客户端需要Bing的服务器公共证书才能开始通信(SSLHandshake),但您的错误是因为Bing的证书不在您的默认Java密钥库中作为可信证书。

你可以做到以下几点:

  • 获取Bing的证书和进口到默认Java密钥使用keytool受信任的证书,您的命名cacerts默认密钥库通常位于JAVA_HOME\jre\lib\security\

keytool -importcert -file bingcertificate.cer -keystore cacerts -alias "bingAlias"

  • 创建一个虚拟SSLSocketFactory以获得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);