由于未知原因,我在oAuth代码上获得了 401代码,以便在Streaming Twitter API上进行连接。我对每个方法进行了三重检查,但我找不到错误。我在互联网上搜索OAuth参数或Twitter API参数,但没有运气。这是代码:
package Configuration;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HttpsURLConnection;
public class OAuth {
private URL URL_BASE;
private String oauth_token;
private String oauth_method;
private String oauth_version;
private String oauth_consumer_key;
private String con_method;
public OAuth() throws MalformedURLException {
this.con_method = "POST";
this.URL_BASE = new URL("https://stream.twitter.com/1.1/statuses/filter.json");
this.oauth_consumer_key = "XXXXXXX";
this.oauth_token = "XXXXXXX";
this.oauth_method = "HMAC-SHA1";
this.oauth_version = "1.0";
}
/**
* Timestamp
*
* The oauth_timestamp parameter indicates when the request was created.
* This value should be the number of seconds since the Unix epoch at the
* point the request is generated, and should be easily generated in most
* programming languages. Twitter will reject requests which were created
* too far in the past, so it is important to keep the clock of the
* computer generating requests in sync with NTP.
*
* @see oauth_timestamp 1318622958
*/
public String oauth_timestamp() {
long millis = System.currentTimeMillis();
long secs = millis / 1000;
return String.valueOf(secs);
}
/**
* Nonce
*
* The oauth_nonce parameter is a unique token your application should generate
* for each unique request. Twitter will use this value to determine whether a
* request has been submitted multiple times. The value for this request was
* generated by base64 encoding 32 bytes of random data, and stripping out all
* non-word characters, but any approach which produces a relatively random
* alphanumeric string should be OK here.
*
* @see oauth_nonce kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg
*/
public String oauth_nounce() {
SecureRandom rdn = new SecureRandom();
String nounce_1 = new BigInteger(130, rdn).toString(32);
String nounce_2 = new BigInteger(130, rdn).toString(32).substring(0, 6);
if((new String(nounce_1 + nounce_2)).length() != 32)
System.out.println("Tamanho do nounce incorreto");
return nounce_1 + nounce_2;
}
/**
* Signature
*
* The oauth_signature parameter contains a value which is generated by
* running all of the other request parameters and two secret values
* through a signing algorithm. The purpose of the signature is so that
* Twitter can verify that the request has not been modified in transit,
* verify the application sending the request, and verify that the
* application has authorization to interact with the user’s account.
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*
* @see oauth_signature tnnArxj06cWHq44gCs1OSKk/jLY=
*/
private String oauth_signature(String message) throws NoSuchAlgorithmException, InvalidKeyException {
Mac sha1 = Mac.getInstance("HmacSHA1");
sha1.init(new SecretKeySpec("CONSUMER_SECRET".getBytes(), "HmacSHA1"));
sha1.update(message.getBytes());
return URLEncoder.encode(String.valueOf(Base64Coder.encode(sha1.doFinal())));
}
public String authenticate() throws InvalidKeyException, MalformedURLException, IOException, NoSuchAlgorithmException {
StringBuffer buffer = new StringBuffer();
String charset = "UTF-8";
String read;
String[][] data =
{
{"oauth_consumer_key" , this.oauth_consumer_key },
{"oauth_nonce" , oauth_nounce() },
{"oauth_signature" , "" },
{"oauth_signature_method", this.oauth_method },
{"oauth_timestamp" , oauth_timestamp() },
{"oauth_token" , this.oauth_token },
{"oauth_version" , this.oauth_version }
};
String sg_base_str = "POST&"+URLEncoder.encode(this.URL_BASE.toString(),charset)+"&";
for(int i = 0; i < data.length; i++)
{
String _26;
if(data.length + 1 < i)
_26 = "%26";
else _26 = "";
if(data[i][0] != "oauth_signature")
{
sg_base_str += URLEncoder.encode(data[i][0],charset) + "%3D"
+ URLEncoder.encode(data[i][1],charset) + _26 ;
}
}
data[2][1] = oauth_signature(sg_base_str);
String header = "OAuth ";
for(String[] item : data)
header += item[0]+"=\""+item[1]+"\", ";
// cut off last appended comma
header = header.substring(0, header.length()-2);
System.out.println("Signature Base String:\n\n" + sg_base_str + "\n");
System.out.println( "Authorization Header:\n\n" + header + "\n\n");
System.setProperty("http.keepAlive", "true");
HttpsURLConnection con = (HttpsURLConnection) this.URL_BASE.openConnection();
con.setInstanceFollowRedirects(true);
con.setDoInput (true);
con.setDoOutput(true);
con.setRequestMethod (this.con_method);
con.setRequestProperty("Accept" , "*/*");
con.setRequestProperty("Connection" , "close");
con.setRequestProperty("Content-Type" , "application/x-www-form-urlencoded");
con.setRequestProperty("Accept-Charset" , charset);
con.setRequestProperty("User-Agent" , "JMiner v1.0");
con.setRequestProperty("Content-length" , "0");
con.setRequestProperty("Host" , "api.twitter.com");
con.setRequestProperty("Authorization" , header);
OutputStream output = con.getOutputStream();
output.write( header.getBytes(charset) );
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
while((read = reader.readLine()) != null)
buffer.append(read);
return buffer.toString();
}
}