如何请求 JSON 在 URL 中有空格?
How to request JSON that have spaces in URL?
当我尝试不使用 space 的 URL 时,它运行良好。
但是,当我添加 space 时,会出现以下错误:
Caused by: java.lang.IllegalArgumentException: Illegal character in
path at index 79:
http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Bachelors
Island Marine.json
当我在浏览器中尝试时,它有效。
PS:我尝试对 URL 进行编码,但出现了同样的错误。
代码:
package com.example.elie.myapplication;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
* Async task class to get json by making HTTP call
* */
public class GetWeatherInfo extends AsyncTask<Void, Void, Void> {
private String mCity;
private OnTaskComplete onTaskComplete;
private ProgressDialog pDialog;
// URL to get Country
private static String url ;
// JSON Node names
private static final String TAG_FORECAST="hourly_forecast";
private static final String TAG_CONDITION="condition";
private static final String TAG_HOUR="hour";
private static final String TAG_DATE="pretty";
private static final String TAG_FCTTIME="FCTTIME";
private static final String TAG_HUMIDITY="humidity";
private static final String TAG_UVI="uvi";
//The calling Activity
private Activity mActivity;
private WeatherInfo mWeather;
//Country name
private String mCountry;
private JSONArray mForecast;
//Constructor
public GetWeatherInfo(Activity act,String country,String city) {
mWeather=new WeatherInfo();
mCountry=country;
mCity=city;
mActivity=act;
url = "http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/"+country+"/"+mCity+".json";
url.replaceAll(" ","%20");
Log.d("URL",url);
this.execute();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(mActivity);
pDialog.setMessage("Getting weather conditions...");
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
mWeather.setCityName(mCity);
mWeather.setCountryName(mCountry);
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
mForecast = jsonObj.getJSONArray(TAG_FORECAST);
// 1st element JSON object
JSONObject firstElement =mForecast.getJSONObject(0);
// FCTTIME JSON object
JSONObject FCTTIME =firstElement.getJSONObject(TAG_FCTTIME);
mWeather.setHour24(Integer.parseInt(FCTTIME.getString(TAG_HOUR)));
mWeather.setDate(FCTTIME.getString(TAG_DATE));
mWeather.setHumidity(Integer.parseInt(firstElement.getString(TAG_HUMIDITY)));
mWeather.setUVIndex(Integer.parseInt(firstElement.getString(TAG_UVI)));
mWeather.setCondition(firstElement.getString(TAG_CONDITION));
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
onTaskComplete.setMyTaskComplete(mWeather);
}
public String getCountry()
{
return mCountry;
}
public interface OnTaskComplete {
public void setMyTaskComplete(WeatherInfo message);
}
public void setMyTaskCompleteListener(OnTaskComplete onTaskComplete) {
this.onTaskComplete = onTaskComplete;
}
}
错误:
02-12 18:43:04.098 5547-6459/com.example.elie.myapplication
E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #3
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.IllegalArgumentException: Illegal character in path at index 80:
http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Addenbroke
Island.json
at java.net.URI.create(URI.java:727)
at org.apache.http.client.methods.HttpGet.(HttpGet.java:75)
at com.example.elie.myapplication.ServiceHandler.makeServiceCall(ServiceHandler.java:68)
at com.example.elie.myapplication.ServiceHandler.makeServiceCall(ServiceHandler.java:34)
at com.example.elie.myapplication.GetWeatherInfo.doInBackground(GetWeatherInfo.java:77)
at com.example.elie.myapplication.GetWeatherInfo.doInBackground(GetWeatherInfo.java:18)
at android.os.AsyncTask.call(AsyncTask.java:287)
Space 个 URL 中的字符必须编码。将 ' '
替换为 %20
.
像这样:
http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Bachelors%20Island%20Marin.json
一般来说你应该使用URLEncoder来编码URL。
url = URLEncoder.encode(url, "UTF-8");
尝试使用“+”或“%20”代替空格。
逃离你的url。
应该是这样的:http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Bachelors%20Island%20Marine.json
假设你有一个字符串作为你的 url ,你可以这样做:
url.replaceAll(" " ,"%20");
编辑
正如许多人所建议的那样,最正确的方法是:
url = URLEncoder.encode(url, "UTF-8");
为了避免以后出现类似的问题。
当我尝试不使用 space 的 URL 时,它运行良好。 但是,当我添加 space 时,会出现以下错误:
Caused by: java.lang.IllegalArgumentException: Illegal character in path at index 79: http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Bachelors Island Marine.json
当我在浏览器中尝试时,它有效。
PS:我尝试对 URL 进行编码,但出现了同样的错误。
代码:
package com.example.elie.myapplication;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
* Async task class to get json by making HTTP call
* */
public class GetWeatherInfo extends AsyncTask<Void, Void, Void> {
private String mCity;
private OnTaskComplete onTaskComplete;
private ProgressDialog pDialog;
// URL to get Country
private static String url ;
// JSON Node names
private static final String TAG_FORECAST="hourly_forecast";
private static final String TAG_CONDITION="condition";
private static final String TAG_HOUR="hour";
private static final String TAG_DATE="pretty";
private static final String TAG_FCTTIME="FCTTIME";
private static final String TAG_HUMIDITY="humidity";
private static final String TAG_UVI="uvi";
//The calling Activity
private Activity mActivity;
private WeatherInfo mWeather;
//Country name
private String mCountry;
private JSONArray mForecast;
//Constructor
public GetWeatherInfo(Activity act,String country,String city) {
mWeather=new WeatherInfo();
mCountry=country;
mCity=city;
mActivity=act;
url = "http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/"+country+"/"+mCity+".json";
url.replaceAll(" ","%20");
Log.d("URL",url);
this.execute();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(mActivity);
pDialog.setMessage("Getting weather conditions...");
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
mWeather.setCityName(mCity);
mWeather.setCountryName(mCountry);
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
mForecast = jsonObj.getJSONArray(TAG_FORECAST);
// 1st element JSON object
JSONObject firstElement =mForecast.getJSONObject(0);
// FCTTIME JSON object
JSONObject FCTTIME =firstElement.getJSONObject(TAG_FCTTIME);
mWeather.setHour24(Integer.parseInt(FCTTIME.getString(TAG_HOUR)));
mWeather.setDate(FCTTIME.getString(TAG_DATE));
mWeather.setHumidity(Integer.parseInt(firstElement.getString(TAG_HUMIDITY)));
mWeather.setUVIndex(Integer.parseInt(firstElement.getString(TAG_UVI)));
mWeather.setCondition(firstElement.getString(TAG_CONDITION));
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
onTaskComplete.setMyTaskComplete(mWeather);
}
public String getCountry()
{
return mCountry;
}
public interface OnTaskComplete {
public void setMyTaskComplete(WeatherInfo message);
}
public void setMyTaskCompleteListener(OnTaskComplete onTaskComplete) {
this.onTaskComplete = onTaskComplete;
}
}
错误:
02-12 18:43:04.098 5547-6459/com.example.elie.myapplication E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #3 java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask.done(AsyncTask.java:299) at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) at java.util.concurrent.FutureTask.setException(FutureTask.java:124) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) at java.util.concurrent.FutureTask.run(FutureTask.java:137) at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:230) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) at java.lang.Thread.run(Thread.java:856) Caused by: java.lang.IllegalArgumentException: Illegal character in path at index 80: http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Addenbroke Island.json at java.net.URI.create(URI.java:727) at org.apache.http.client.methods.HttpGet.(HttpGet.java:75) at com.example.elie.myapplication.ServiceHandler.makeServiceCall(ServiceHandler.java:68) at com.example.elie.myapplication.ServiceHandler.makeServiceCall(ServiceHandler.java:34) at com.example.elie.myapplication.GetWeatherInfo.doInBackground(GetWeatherInfo.java:77) at com.example.elie.myapplication.GetWeatherInfo.doInBackground(GetWeatherInfo.java:18) at android.os.AsyncTask.call(AsyncTask.java:287)
Space 个 URL 中的字符必须编码。将 ' '
替换为 %20
.
像这样:
http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Bachelors%20Island%20Marin.json
一般来说你应该使用URLEncoder来编码URL。
url = URLEncoder.encode(url, "UTF-8");
尝试使用“+”或“%20”代替空格。
逃离你的url。 应该是这样的:http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Bachelors%20Island%20Marine.json
假设你有一个字符串作为你的 url ,你可以这样做:
url.replaceAll(" " ,"%20");
编辑
正如许多人所建议的那样,最正确的方法是:
url = URLEncoder.encode(url, "UTF-8");
为了避免以后出现类似的问题。