3

I'm having trouble with JSON transfer in Android. I receive the following error in 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

This the Android code that I am trying to run

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

It has to be something with the GET call. I'm not sure what exactly it is, but all my System.out print up to that part of the program...

Thanks in advance for any help!

4

6 回答 6

4

首先 ,您正在传递一个包含空格的查询字符串,这将破坏 url。因此,您需要encode在发送前执行:

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

第二

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

于 2013-04-29T05:09:17.090 回答
2

尝试 :

String requestLink = "http://SOME_WEBSITE/api/api.php?package="+json.toString();
String finalRequestString = URLEncoder.encode(requestLink,"UTF-8");
于 2013-04-29T05:08:00.030 回答
1
java.lang.IllegalArgumentException: Illegal character in query

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

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

于 2013-04-29T05:07:37.147 回答
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();
    }
}
于 2013-04-29T05:07:55.117 回答
1

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

查看这篇文章以了解如何对您的 url 进行编码: 查询字符串参数的 Java URL 编码

于 2013-04-29T05:08:50.220 回答
1

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

package=    {

你看到等号和左花括号之间的空格了吗?

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

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

于 2013-04-29T05:09:32.130 回答