如何请求在URL中有空格的JSON?

时间:2015-02-12 16:34:00

标签: android json encoding spaces

当我尝试没有空格的URL时,它完美地运行。 但是,当我添加空格时,它会给我以下错误:

  

引起:java.lang.IllegalArgumentException:非法字符   索引79处的路径:   http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Bachelors   Island Marine.json

当我在浏览器中尝试它时,它可以工作 PS:我尝试编码URL并发生了同样的错误。

CODE:

    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;
    }
}

ERROR:

  

02-12 18:43:04.098 5547-6459 / com.example.elie.myapplication   E / AndroidRuntime:FATAL EXCEPTION:AsyncTask#3       java.lang.RuntimeException:执行doInBackground()时发生错误               在android.os.AsyncTask $ 3.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)               在java.util.concurrent.FutureTask.run(FutureTask.java:137)               在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:230)               在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)               at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:569)               在java.lang.Thread.run(Thread.java:856)        引起:java.lang.IllegalArgumentException:索引80处路径中的非法字符:   http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Addenbroke   Island.json               在java.net.URI.create(URI.java:727)               在org.apache.http.client.methods.HttpGet。(HttpGet.java:75)               在com.example.elie.myapplication.ServiceHandler.makeServiceCall(ServiceHandler.java:68)               在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)               在android.os.AsyncTask $ 2.call(AsyncTask.java:287)

3 个答案:

答案 0 :(得分:6)

逃离你的网址。 应该是这样的:http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Bachelors%20Island%20Marine.json

假设你有一个String作为你的网址,你可以这样做:

 url.replaceAll(" " ,"%20");

修改

正如许多人所说,最正确的方法是:

 url = URLEncoder.encode(url, "UTF-8");

为了避免将来出现这类问题。

答案 1 :(得分:2)

必须对URL中的空格字符进行编码。将' '替换为%20

像这样:

http://api.wunderground.com/api/81eb946ab954bdcb/hourly/lang/q/Canada/Bachelors%20Island%20Marin.json

通常,您应该使用URLEncoder对网址进行编码。

url = URLEncoder.encode(url, "UTF-8");

答案 2 :(得分:0)