为什么我的 Android 应用程序连接到 Reddit API,但收到空白响应?
Why is my Android app connecting to the Reddit API, but getting a blank response?
我正在尝试学习如何连接到 API 并接收和解析 JSON 数据,因此我目前正在关注此网页上的示例:http://www.whycouch.com/2012/12/how-to-create-android-client-for-reddit.html,但我收到一条错误消息:
E/fetchPosts(): org.json.JSONException: End of input at character 0 of
我的应用程序正在连接,因为它说已经建立了一个新的主机连接,所以我不太确定为什么它会收到空白响应。下面是我的 class 获取连接并读取内容。如果我不得不猜测我哪里出错了,我会说它与请求属性有关,但我去了 reddit 的网站并按照他们想要的方式对其进行了格式化,但它仍然没有返回任何内容。谢谢。
public class RemoteData {
/*
This method returns a connection to the specified URL,
with necessary properties like timeout and user-agent
set to your requirements.
*/
public static HttpURLConnection getConnection(String url){
System.out.println("URL: " + url);
HttpURLConnection hcon = null;
try{
hcon = (HttpURLConnection)new URL(url).openConnection();
hcon.setReadTimeout(30000); //Timeout set at 30 seconds
hcon.setRequestProperty("User-Agent", "android:com.example.reddittestappbydrew:v0.0.1");
}catch(MalformedURLException e){
Log.e("getConnection()", "Invalid URL: " +e.toString());
}catch (IOException e){
Log.e("getConnection()", "Could not connect: " + e.toString());
}
return hcon;
}
/*
A utility method that reads the contents of a url and returns them as a string
*/
public static String readContents(String url){
HttpURLConnection hcon = getConnection(url);
if(hcon == null) return null;
try{
StringBuffer sb = new StringBuffer(8192);
String tmp = "";
BufferedReader br = new BufferedReader(new InputStreamReader(hcon.getInputStream()));
while((tmp = br.readLine()) != null){
sb.append(tmp).append("\n");
}
br.close();
return sb.toString();
}catch(IOException e){
Log.d("READ FAILED", e.toString());
return null;
}
}
}
您编写的代码对于从我的 URL 获取 html/json 响应数据看起来非常天真,因为那里没有处理重定向。您可以在代码中处理重定向,您可以通过检查 hcon.getResponseCode() 的值应为 200 来成功读取数据。如果它不是 200 而不是 301(重定向)或 403(需要授权)之类的东西,您需要相应地处理这些响应。
这里我给你一个简单的代码,它使用来自 apache 的 HttpClient(我正在使用 httpclient-4.2.1)库,并以字符串形式返回响应。
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.commons.fileupload.util.Streams;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpUtils {
private static Logger LOGGER = LoggerFactory.getLogger(HttpUtils.class);
public static String getResponse(String url) throws IOException {
return getResponse(url, "UTF-8");
}
public static String getResponse(String url, String characterEncoding) throws IOException {
return getByteArrayOutputStream(url).toString(characterEncoding);
}
public static byte[] getBytes(String url) throws IOException {
return getByteArrayOutputStream(url).toByteArray();
}
public static ByteArrayOutputStream getByteArrayOutputStream(String url) throws IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpclient.execute(httpGet);
LOGGER.debug("Status Line: " + response.getStatusLine());
HttpEntity resEntity = response.getEntity();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Streams.copy(resEntity.getContent(), byteArrayOutputStream, true);
return byteArrayOutputStream;
}
public static void main(String[] args) throws IOException {
System.out.println(getResponse("https://www.reddit.com/r/AskReddit/.json"));
}
}
使用这段代码来实现你想要的,如果你不想使用 HTTPClient API,那么修改你现有的代码来处理 http 状态代码,但是你在上面使用它会很简单代码。
我正在尝试学习如何连接到 API 并接收和解析 JSON 数据,因此我目前正在关注此网页上的示例:http://www.whycouch.com/2012/12/how-to-create-android-client-for-reddit.html,但我收到一条错误消息:
E/fetchPosts(): org.json.JSONException: End of input at character 0 of
我的应用程序正在连接,因为它说已经建立了一个新的主机连接,所以我不太确定为什么它会收到空白响应。下面是我的 class 获取连接并读取内容。如果我不得不猜测我哪里出错了,我会说它与请求属性有关,但我去了 reddit 的网站并按照他们想要的方式对其进行了格式化,但它仍然没有返回任何内容。谢谢。
public class RemoteData {
/*
This method returns a connection to the specified URL,
with necessary properties like timeout and user-agent
set to your requirements.
*/
public static HttpURLConnection getConnection(String url){
System.out.println("URL: " + url);
HttpURLConnection hcon = null;
try{
hcon = (HttpURLConnection)new URL(url).openConnection();
hcon.setReadTimeout(30000); //Timeout set at 30 seconds
hcon.setRequestProperty("User-Agent", "android:com.example.reddittestappbydrew:v0.0.1");
}catch(MalformedURLException e){
Log.e("getConnection()", "Invalid URL: " +e.toString());
}catch (IOException e){
Log.e("getConnection()", "Could not connect: " + e.toString());
}
return hcon;
}
/*
A utility method that reads the contents of a url and returns them as a string
*/
public static String readContents(String url){
HttpURLConnection hcon = getConnection(url);
if(hcon == null) return null;
try{
StringBuffer sb = new StringBuffer(8192);
String tmp = "";
BufferedReader br = new BufferedReader(new InputStreamReader(hcon.getInputStream()));
while((tmp = br.readLine()) != null){
sb.append(tmp).append("\n");
}
br.close();
return sb.toString();
}catch(IOException e){
Log.d("READ FAILED", e.toString());
return null;
}
}
}
您编写的代码对于从我的 URL 获取 html/json 响应数据看起来非常天真,因为那里没有处理重定向。您可以在代码中处理重定向,您可以通过检查 hcon.getResponseCode() 的值应为 200 来成功读取数据。如果它不是 200 而不是 301(重定向)或 403(需要授权)之类的东西,您需要相应地处理这些响应。
这里我给你一个简单的代码,它使用来自 apache 的 HttpClient(我正在使用 httpclient-4.2.1)库,并以字符串形式返回响应。
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.commons.fileupload.util.Streams;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpUtils {
private static Logger LOGGER = LoggerFactory.getLogger(HttpUtils.class);
public static String getResponse(String url) throws IOException {
return getResponse(url, "UTF-8");
}
public static String getResponse(String url, String characterEncoding) throws IOException {
return getByteArrayOutputStream(url).toString(characterEncoding);
}
public static byte[] getBytes(String url) throws IOException {
return getByteArrayOutputStream(url).toByteArray();
}
public static ByteArrayOutputStream getByteArrayOutputStream(String url) throws IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpclient.execute(httpGet);
LOGGER.debug("Status Line: " + response.getStatusLine());
HttpEntity resEntity = response.getEntity();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Streams.copy(resEntity.getContent(), byteArrayOutputStream, true);
return byteArrayOutputStream;
}
public static void main(String[] args) throws IOException {
System.out.println(getResponse("https://www.reddit.com/r/AskReddit/.json"));
}
}
使用这段代码来实现你想要的,如果你不想使用 HTTPClient API,那么修改你现有的代码来处理 http 状态代码,但是你在上面使用它会很简单代码。