我正在通过REST API验证外部系统。 http身份验证请求的格式为Basic Authorization。响应采用JSON格式。
我在AsyncTask
下运行此代码。
url
API的GET网址。credentials
是身份验证凭据。这是一个字符串。response
是文字视图。getmessage
是一个字符串变量。connection = (HttpURLConnection)new URL(url).openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Authorization", "Basic" + Base64.encode(credentials.getBytes(), Base64.DEFAULT ));
// I am reading the response here,
InputStreamReader in = new InputStreamReader(connection.getInputStream());
buf = new BufferedReader(in);
getmessage = buf.readLine();
// After making the request, I am updating the response to a text view on the UI thread
runOnUiThread(new Runnable() {
@Override
public void run() {
response.setText(getmessage);
}
});
我无法将整个JSON数据写入文本视图。我知道buf.readline
会将响应返回到行尾。现在我只得到了JSON响应的一部分,"未经过身份验证:",但我需要整个响应。
如何更新文本视图的整个JSON响应(response
)?如果我在循环中使用buf.readline
循环数据,那么我可以在哪里使用它?在哪个线程?
如果我的代码中有任何异常。请告诉我。
答案 0 :(得分:1)
我建议你去AsyncTask
private class GetDataFromUrl extends AsyncTask<URL, Integer, String> {
protected String doInBackground(URL... urls) {
connection = (HttpURLConnection)new URL(url).openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Authorization", "Basic" + Base64.encode(credentials.getBytes(), Base64.DEFAULT ));
InputStreamReader in = new InputStreamReader(connection.getInputStream());
buf = new BufferedReader(in);
StringBuilder sb = new StringBuilder();
while ((getmessage = buf.readLine()) != null) {
sb.append(getmessage);
}
getmessage = sb.toString();
return getmessage;
}
protected void onPostExecute(String result) {
// Result will be available here (this runs on main thread)
// Show result in text view here.
response.setText(result);
}
}
为了更好地理解,当您调用AsyncTask
时,doInBackground
会在创建的新线程上运行。放置网络呼叫和解析数据的位置。现在,我们需要访问主线程上的数据来更新TextView
,以便在onPostExecute
内覆盖AsyncTask
,result
作为参数,来自{{1} }。如果你注意到..
doInBackground
此处private class GetDataFromUrl extends AsyncTask<URL, Integer, String>
是我们传递给URL
的{{1}}
AsyncTask
是我们从doInBackground
传递到String
和doInBackground
用于显示您可以覆盖的另一种方法的进度,即onPostExecute
..您可以在上面提到的文档中阅读更多内容。希望它有所帮助。
答案 1 :(得分:0)
您只是使用readLine()读取响应的第一行。在循环中调用它直到读取所有行,并将每个新行附加到前一行。
答案 2 :(得分:0)
试试这个:
StringBuilder sb = new StringBuilder();
while ((getmessage = buf.readLine()) != null) {
sb.append(getmessage);
}
getmessage = sb.toString();
<强> EDITED 强>
在您的代码中:
getmessage = buf.readLine();
变量getmessage中的只读取JSON的第一行。您需要读取所有行并将其连接起来。如何知道你是否读过所有行?
以下是documentation对此的说法:
public String readLine() 抛出IOException
<强>返回:强>
包含该行内容的字符串,不包括任何内容 行终止字符,或null 如果流已结束 达到
正如您所看到的,您应该调用此方法,将结果保存到变量中,并检查,如果变量非空,则您具有JSON的读取行。如果变量是 null ,那么您已将所有JSON读入变量,并且您已完全使用JSON字符串。
StringBuilder 用于避免创建不必要的对象,请阅读更多相关信息here
答案 3 :(得分:0)
如果我理解正确,你会尝试逐行读取所有响应数据。你能试试以下吗?
@Override
protected String doInBackGround(...){
. . .
BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream), 8 * 1024);
String line = "";
StringBuilder sb = new StringBuilder();
while ((line = rd.readLine()) != null) {
sb.append(line);
}
String response = sb.toString();
return response;
}
@Override
protected void onPostExecute(String response){
Textview tv = your_textview;
your_textview.settext(whatever_part_you_get_from_response);
}
希望这有帮助。