JSON数据错误Android Illegal Argument HttpClient

时间:2013-04-29 04:58:52

标签: java android json http-get

我在Android中JSON转移时遇到问题。我在LogCat中收到以下错误。

04-29 04:47:11.362: E/Trace(851): error opening trace file: No such file or directory (2)
04-29 04:47:12.243: I/System.out(851): 1
04-29 04:47:12.243: I/System.out(851): 2
04-29 04:47:12.303: W/System.err(851): java.lang.IllegalArgumentException: Illegal character in query     at index 42: http://SOME_WEBSITE/api/api.php?package=    {"key":"SOME_KEY","info":{"type":"user","login":{"password":"some_password","email":"test@gmail.    com"}},"request":"info"}
04-29 04:47:12.313: W/System.err(851):  at java.net.URI.create(URI.java:727)
04-29 04:47:12.333: W/System.err(851):  at org.apache.http.client.methods.HttpGet.<init>(HttpGet.    java:75)
04-29 04:47:12.333: W/System.err(851):  at com.example.jsontest.MainActivity.onCreate(MainActivity.    java:47)
04-29 04:47:12.333: W/System.err(851):  at android.app.Activity.performCreate(Activity.java:5104)
04-29 04:47:12.333: W/System.err(851):  at android.app.Instrumentation.callActivityOnCreate(    Instrumentation.java:1080)
04-29 04:47:12.333: W/System.err(851):  at android.app.ActivityThread.performLaunchActivity(    ActivityThread.java:2144)
04-29 04:47:12.343: W/System.err(851):  at android.app.ActivityThread.handleLaunchActivity(    ActivityThread.java:2230)
04-29 04:47:12.343: W/System.err(851):  at android.app.ActivityThread.access$600(ActivityThread.    java:141)
04-29 04:47:12.343: W/System.err(851):  at android.app.ActivityThread$H.handleMessage(ActivityThread.    java:1234)
04-29 04:47:12.343: W/System.err(851):  at android.os.Handler.dispatchMessage(Handler.java:99)
04-29 04:47:12.343: W/System.err(851):  at android.os.Looper.loop(Looper.java:137)
04-29 04:47:12.343: W/System.err(851):  at android.app.ActivityThread.main(ActivityThread.java:5041)
04-29 04:47:12.343: W/System.err(851):  at java.lang.reflect.Method.invokeNative(Native Method)
04-29 04:47:12.402: W/System.err(851):  at java.lang.reflect.Method.invoke(Method.java:511)
04-29 04:47:12.402: W/System.err(851):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(    ZygoteInit.java:793)
04-29 04:47:12.402: W/System.err(851):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
04-29 04:47:12.402: W/System.err(851):  at dalvik.system.NativeStart.main(Native Method)
04-29 04:47:12.402: I/System.out(851): Something is wrong

这是我尝试运行的Android代码

public class MainActivity extends Activity 
{       
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView the_text_view = (TextView) findViewById(R.id.name);

        //Construct the JSON
        JSONObject json = new JSONObject();
        JSONObject info_json = new JSONObject();
        JSONObject login_info = new JSONObject();

        try
        {    
            login_info.put("email", "test@gmail.com");
            login_info.put("password", "some_password");

            info_json.put("type", "user");
            info_json.put("login", login_info);

            json.put("key", "SOME_KEY");
            json.put("request", "info");
            json.put("info", info_json);

            HttpClient httpClient = new DefaultHttpClient();
            System.out.println("1");
            String requestLink = "http://SOME_WEBSITE/api/api.php?package="+json.toString();
            System.out.println("2");        
            HttpGet httpGet = new HttpGet(requestLink);
            System.out.println("3");
            HttpResponse httpResponseGet = httpClient.execute(httpGet);
            System.out.println("4");
            HttpEntity resEntityGet = httpResponseGet.getEntity();
            System.out.println("5");

            if (resEntityGet != null) 
            {
                String response = EntityUtils.toString(resEntityGet);             
                JSONObject json_response = new JSONObject(response);             
                System.out.println(json.toString());
            }

            System.out.println("Looks alright");
        }
        catch (Exception e) 
        {
            e.printStackTrace();  
            System.out.println("Something is wrong");
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

必须是GET电话。我不确定它究竟是什么,但是我的所有System.out都打印到该程序的那一部分......

提前感谢您的帮助!

6 个答案:

答案 0 :(得分:4)

<强>第一 您正在传递一个查询字符串,其中包含空格,这将破坏该网址。因此,您需要在发送之前执行encode

String requestLink = "http://SOME_WEBSITE/api/api.php?package="+Encoder.encode(json.toString(),"UTF-8");

<强>第二

您正尝试在UI线程上执行网络操作,这在Android 3.0+中是不允许的,并且会抛出NetworkOnMainThreadException。使用AsyncTask或单独的线程执行网络操作。

答案 1 :(得分:2)

尝试:

String requestLink = "http://SOME_WEBSITE/api/api.php?package="+json.toString();
String finalRequestString = URLEncoder.encode(requestLink,"UTF-8");

答案 2 :(得分:1)

java.lang.IllegalArgumentException: Illegal character in query

您的get请求中的字符在URL中不合法。在GET请求中传递字符串之前,您必须对其进行URL编码。有关详细信息,请参阅:

https://en.wikipedia.org/wiki/Percent-encoding

答案 3 :(得分:1)

我希望这会对您有所帮助。在这个类中,两个方法都被编码。在此,您还可以传递所需的参数。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.json.JSONException;
import org.json.JSONObject;

public class JsonClient {

    public enum RequestMethod{
        GET,
        POST
    }

    private ArrayList <NameValuePair> params;
    private ArrayList <NameValuePair> headers;

    private String url;

    private int responseCode;
    private String message;

    private JSONObject jsonResponse;

    public JSONObject getResponse() {
        return jsonResponse;
    }

    public String getErrorMessage() {
        return message;
    }

    public int getResponseCode() {
        return responseCode;
    }

    public JsonClient(String url)
    {
        this.url = url;
        params = new ArrayList<NameValuePair>();
        headers = new ArrayList<NameValuePair>();
    }

    public void addParam(String name, String value)
    {
        params.add(new BasicNameValuePair(name, value));
    }

    public void addHeader(String name, String value)
    {
        headers.add(new BasicNameValuePair(name, value));
    }

    public void execute(RequestMethod method) throws Exception
    {
        switch(method) {
        case GET:
        {
            //add parameters
            String combinedParams = "";
            if(!params.isEmpty()){
                combinedParams += "?";
                for(NameValuePair p : params)
                {
                    String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue(),"UTF-8");
                    if(combinedParams.length() > 1)
                    {
                        combinedParams  +=  "&" + paramString;
                    }
                    else
                    {
                        combinedParams += paramString;
                    }
                }
            }

            HttpGet request = new HttpGet(url + combinedParams);

            //add headers
            for(NameValuePair h : headers)
            {
                request.addHeader(h.getName(), h.getValue());
            }

            executeRequest(request, url);
            break;
        }
        case POST:
        {
            HttpPost request = new HttpPost(url);

            //add headers
            for(NameValuePair h : headers)
            {
                request.addHeader(h.getName(), h.getValue());
            }

            if(!params.isEmpty()){
                request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
            }

            executeRequest(request, url);
            break;
        }
        }
    }

    private void executeRequest(HttpUriRequest request, String url)
    {
        HttpClient client = new DefaultHttpClient();

        HttpResponse httpResponse;

        try {
            httpResponse = client.execute(request);
            responseCode = httpResponse.getStatusLine().getStatusCode();
            message = httpResponse.getStatusLine().getReasonPhrase();

            HttpEntity entity = httpResponse.getEntity();

            if (entity != null) {

                InputStream instream = entity.getContent();
                String  response = convertStreamToString(instream);
                jsonResponse = new JSONObject(response);

                // Closing the input stream will trigger connection release
                instream.close();
            }

        } catch (ClientProtocolException e)  {
            client.getConnectionManager().shutdown();
            e.printStackTrace();
        } catch (IOException e) {
            client.getConnectionManager().shutdown();
            e.printStackTrace();
        }catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private static 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();
    }
}

答案 4 :(得分:1)

如果你想将JSON用作'GET'(即作为url的一部分),那么你需要对字符串进行编码。例如,请注意当您在浏览器中输入空格时,它会将其转换为%20。这是因为url不能包含空格。

查看此帖子,了解如何对网址进行编码: Java URL encoding of query string parameters

答案 5 :(得分:1)

LogCat输出显示您尝试用于GET请求的requestLink字符串中的一些空格。这是LogCat的相关位

package=    {

你看到等号和开口大括号之间的空格?

在将JSON字符串连接到基本URL之前,您应该修剪空格。您还应该考虑使用Uri解析方法来确保所有字符都已正确编码,http://developer.android.com/reference/android/net/Uri.html#parse(java.lang.String)

最后,您确定要将大JSON字符串附加到基本URL吗?这似乎有点奇怪,但如果API要求它,上面的建议应该可以解决你的问题。