[英]StringIndexOutOfBoundsException error while parsing JSON
I have been using this helper class to parse JSON data for a while now but upon doing updates the app crashes the 2nd time it is used at any point while the app is running. 我一直在使用该帮助器类来解析JSON数据已有一段时间了,但是在进行更新时,应用程序在运行时的任何时候都会第二次使用它时崩溃。 I can't seem to figure out why this is happening.
我似乎无法弄清楚为什么会这样。
Update 2 更新2
The issue is with redirects and has nothing to do with cookies but I was able to fix my problem. 问题是重定向,与Cookie无关,但我可以解决我的问题。 Check my answer for solution.
检查我的答案以寻求解决方案。
Update 1 更新1
After Aaron's suggestion. 在亚伦的建议之后。 I in fact don't get any JSON back after the first request.
实际上,在第一个请求之后我没有得到任何JSON。 If this is an issue with a cookie why does it work the first time?
如果这是Cookie的问题,为什么它第一次起作用?
HTTP/1.1 302 Moved Temporarily
Content-Type: text/html; charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Date: Tue, 03 Jan 2017 13:31:59 GMT
Location: https://docs.google.com/spreadsheets/d/I REMOVED THE KEY/gviz/tq
P3P: CP="This is not a P3P policy! See https://support.google.com/accounts/answer/151657?hl=en for more info."
P3P: CP="This is not a P3P policy! See https://support.google.com/accounts/answer/151657?hl=en for more info."
MainActivity 主要活动
new DownloadWebpageTask1(new AsyncResult1() {
@Override
public void onResult(JSONObject object) {
processJson(object);
}
}).execute("SOMEWEBSITE");
DownloadWebpageTask1.class DownloadWebpageTask1.class
public class DownloadWebpageTask1 extends AsyncTask<String, Void, String> {
com.test.test.AsyncResult1 callback;
public DownloadWebpageTask1(com.test.test.AsyncResult1 callback) {
this.callback = callback;
}
@Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to download the requested page.";
}
}
// onPostExecute displays the results of the AsyncTask.
@Override
protected void onPostExecute(String result) {
// remove the unnecessary parts from the response and construct a JSON
int start = result.indexOf("{", result.indexOf("{") + 1);
int end = result.lastIndexOf("}");
String jsonResponse = result.substring(start, end);
Log.i("Error", jsonResponse);
try {
JSONObject table = new JSONObject(jsonResponse);
callback.onResult(table);
} catch (JSONException e) {
e.printStackTrace();
}
}
private String downloadUrl(String urlString) throws IOException {
InputStream is = null;
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(30000 /* milliseconds */);
conn.setConnectTimeout(30000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int responseCode = conn.getResponseCode();
is = conn.getInputStream();
String contentAsString = convertStreamToString(is);
return contentAsString;
} finally {
if (is != null) {
is.close();
}
}
}
private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
JSON JSON格式
/*O_o*/
google.visualization.Query.setResponse({"version":"0.6","reqId":"0","status":"ok","sig":"806967004","table":{"cols":[{"id":"A","label":"Date","type":"date","pattern":"M/d/yyyy"},{"id":"B","label":"Name","type":"string"},{"id":"C","label":"News","type":"string"},{"id":"D","label":"url","type":"string"},{"id":"E","label":"icon","type":"string"},{"id":"F","label":"picture","type":"string"}],"rows":[{"c":[{"v":"Date(2017,0,2)","f":"1/2/2017"},{"v":"Event 1"},{"v":"This is some event data for event 1"},{"v":""},{"v":"/icon1.png"},{"v":"Test"}]},{"c":[{"v":"Date(2017,0,2)","f":"1/2/2017"},{"v":"Event 2"},{"v":"This is some event data for event 2"},{"v":"https://www.google.com/"},{"v":"/icon2.png"},{"v":"test"}]},{"c":[{"v":"Date(2016,11,30)","f":"12/30/2016"},{"v":"Event 3"},{"v":"This is some event data for event 3"},{"v":""},{"v":"/icon3.png"},{"v":"test"}]},{"c":[{"v":"Date(2016,11,30)","f":"12/30/2016"},{"v":"Event 4"},{"v":"This is some event data for event 4"},{"v":""},{"v":"/icon4.png"},{"v":"test"}]},{"c":[{"v":"Date(2016,11,30)","f":"12/30/2016"},{"v":"Event 5"},{"v":"This is some event data for event 5"},{"v":"https://www.google.com/"},{"v":"/icon5.png"},{"v":"test"}]}]}});
Error 错误
W/System.err: java.net.SocketTimeoutException: Read timed out
W/System.err: at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_read(Native Method)
W/System.err: at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:664)
W/System.err: at libcore.net.http.UnknownLengthHttpInputStream.read(UnknownLengthHttpInputStream.java:41)
W/System.err: at java.io.InputStreamReader.read(InputStreamReader.java:244)
W/System.err: at java.io.BufferedReader.fillBuf(BufferedReader.java:130)
W/System.err: at java.io.BufferedReader.readLine(BufferedReader.java:354)
W/System.err: at com.test.test.DownloadWebpageTask1.convertStreamToString(DownloadWebpageTask1.java:84)
W/System.err: at com.test.test.DownloadWebpageTask1.downloadUrl(DownloadWebpageTask1.java:69)
W/System.err: at com.test.test.DownloadWebpageTask1.doInBackground(DownloadWebpageTask1.java:32)
W/System.err: at com.test.test.DownloadWebpageTask1.doInBackground(DownloadWebpageTask1.java:20)
W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:287)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:234)
W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
W/System.err: at java.lang.Thread.run(Thread.java:856)
W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa6165908)
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.StringIndexOutOfBoundsException: length=1566; regionStart=-1; regionLength=0
at java.lang.String.startEndAndLength(String.java:583)
at java.lang.String.substring(String.java:1464)
at com.test.test.DownloadWebpageTask1.onPostExecute(DownloadWebpageTask1.java:44)
at com.test.test.DownloadWebpageTask1.onPostExecute(DownloadWebpageTask1.java:20)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
I think that the problem is related to the json string ( result
variable). 我认为问题与json字符串(
result
变量)有关。 I expect that it doesn't contain ' {
' character therefore this part of code 我希望它不包含'
{
'字符,因此这部分代码
int start = result.indexOf("{", result.indexOf("{") + 1);
int end = result.lastIndexOf("}");
String jsonResponse = result.substring(start, end);
throws the exception 引发异常
This is an issue having to do with redirects. 这是与重定向有关的问题。 Google changed the URL where JSON data is pulled from.
Google更改了从其中提取JSON数据的URL。
In your URL request change 在您的网址请求中进行更改
https://spreadsheets.google.com/tq?key=YOUR_KEY_HERE
To 至
https://docs.google.com/spreadsheets/d/YOUR_KEY_HERE/gviz/tq
And some slightly modified code from https://stackoverflow.com/a/40105282/6147989 and everything will be up and running. 以及来自https://stackoverflow.com/a/40105282/6147989的一些经过稍微修改的代码,一切将正常运行。
private String downloadUrl(String urlString) throws IOException {
String temp = "";
try {
URL obj = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setReadTimeout(5000);
conn.addRequestProperty("Accept-Language", "en-US,en;q=0.8");
conn.addRequestProperty("User-Agent", "Mozilla");
conn.addRequestProperty("Referer", "google.com");
System.out.println("Request URL ... " + urlString);
boolean redirect = false;
// normally, 3xx is redirect
int status = conn.getResponseCode();
if (status != HttpURLConnection.HTTP_OK) {
if (status == HttpURLConnection.HTTP_MOVED_TEMP
|| status == HttpURLConnection.HTTP_MOVED_PERM
|| status == HttpURLConnection.HTTP_SEE_OTHER)
redirect = true;
}
System.out.println("Response Code ... " + status);
if (redirect) {
// get redirect url from "location" header field
String newUrl = conn.getHeaderField("Location");
// get the cookie if need, for login
String cookies = conn.getHeaderField("Set-Cookie");
// open the new connnection again
conn = (HttpURLConnection) new URL(newUrl).openConnection();
conn.setRequestProperty("Cookie", cookies);
conn.addRequestProperty("Accept-Language", "en-US,en;q=0.8");
conn.addRequestProperty("User-Agent", "Mozilla");
conn.addRequestProperty("Referer", "google.com");
System.out.println("Redirect to URL : " + newUrl);
}
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer html = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
html.append(inputLine);
}
in.close();
System.out.println("URL Content... \n" + html.toString());
System.out.println("Done");
temp = html.toString();
} catch (Exception e) {
e.printStackTrace();
}
return temp;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.