我正在尝试使用Reddit API来做一些事情。我有一切工作,但更改页面和登录。
我需要登录才能使用我的程序,我知道如何使用我得到的cookie,但我无法登录。
以下是代码:
public static Login POST(URL url, String user, String pw) throws IOException
{
String encodedData = URLEncoder.encode("api_type=json&user=" + user +"&passwd="+pw, "UTF-8");
HttpURLConnection ycConnection = null;
ycConnection = (HttpURLConnection) url.openConnection();
ycConnection.setRequestMethod("POST");
ycConnection.setDoOutput(true);
ycConnection.setUseCaches (false);
ycConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
PrintWriter out = new PrintWriter(ycConnection.getOutputStream());
out.print(encodedData.getBytes());
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(ycConnection.getInputStream()));
String response = in.readLine();
Map<String, List<String>> headers = ycConnection.getHeaderFields();
List<String> values = headers.get("Set-Cookie");
String cookieValue = null;
for (java.util.Iterator<String> iter = values.iterator(); iter.hasNext(); ) {
String v = iter.next();
if (cookieValue == null)
cookieValue = v;
else
cookieValue = cookieValue + ";" + v;
}
return new Login(cookieValue, response);
}
我得到的最典型的例外是:
java.io.IOException:服务器返回HTTP响应代码:504为URL:http://www.reddit.com/api/login/kagnito/ at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
但我也收到了很多“无效密码”消息。
我如何解决这个问题?已经好几个小时了!
顺便说一下。这就是我无法理解的问题:https://github.com/reddit/reddit/wiki/API%3A-login 我不知道如何发布这个?它应该进入标题,还是? 我不熟悉HTTP协议。 (因此我的项目 - 我正在学习)
答案 0 :(得分:10)
如果不深入研究为什么其余部分可能不起作用,那么就存在以下问题:
使用URLEncoder
对帖子数据进行编码:您的帖子数据不会进入网址,因此请勿对其进行编码。
您没有设置Content-Length
标题。
以下是您应该开始使用的内容:
public static Login POST(URL url, String user, String pw) throws IOException
{
String data= "api_type=json&user=" + user +"&passwd="+pw;
HttpURLConnection ycConnection = null;
ycConnection = (HttpURLConnection) url.openConnection();
ycConnection.setRequestMethod("POST");
ycConnection.setDoOutput(true);
ycConnection.setUseCaches (false);
ycConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
ycConnection.setRequestProperty("Content-Length", data.length());
PrintWriter out = new PrintWriter(ycConnection.getOutputStream());
out.print(data.getBytes());
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(ycConnection.getInputStream()));
String response = in.readLine();
Map<String, List<String>> headers = ycConnection.getHeaderFields();
List<String> values = headers.get("Set-Cookie");
String cookieValue = null;
for (java.util.Iterator<String> iter = values.iterator(); iter.hasNext(); ) {
String v = iter.next();
if (cookieValue == null)
cookieValue = v;
else
cookieValue = cookieValue + ";" + v;
}
return new Login(cookieValue, response);
}
使用这样的API时,你应该最终安装Fiddler这是HTTP调试器。您会立即看到问题,因为您的帖子数据看起来与示例完全不同。
<强> 更新: 强>
这是一个我刚刚参加测试的一些代码,它对我进行了身份验证(很明显将myusername
和mypassword
更改为你的(不要忘记在URL中更改它):
@Test
public void someTest() throws IOException
{
URL u = new URL( "https://ssl.reddit.com/api/login/myusername" );
login( u, "myusername", "mypassword" );
}
public static void login( URL url, String user, String pw ) throws IOException
{
String data = "api_type=json&user=" + user + "&passwd=" + pw;
HttpURLConnection ycConnection = null;
ycConnection = ( HttpURLConnection ) url.openConnection();
ycConnection.setRequestMethod( "POST" );
ycConnection.setDoOutput( true );
ycConnection.setUseCaches( false );
ycConnection.setRequestProperty( "Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8" );
ycConnection.setRequestProperty( "Content-Length", String.valueOf( data.length() ) );
DataOutputStream wr = new DataOutputStream(
ycConnection.getOutputStream() );
wr.writeBytes( data );
wr.flush();
wr.close();
InputStream is = ycConnection.getInputStream();
BufferedReader rd = new BufferedReader( new InputStreamReader( is ) );
String line;
StringBuffer response = new StringBuffer();
while ( ( line = rd.readLine() ) != null )
{
response.append( line );
response.append( '\r' );
}
for ( Entry< String, List< String >> r : ycConnection.getHeaderFields().entrySet() )
{
System.out.println( r.getKey() + ": " + r.getValue() );
}
rd.close();
System.out.println( response.toString() );
}