2013-04-29 25 views
3

我在Android中轉移JSON時遇到問題。我在LogCat中收到以下錯誤。JSON數據錯誤Android非法參數HttpClient

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":"[email protected] 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 

,我試圖運行

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", "[email protected]"); 
      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調用Android的代碼。我不知道究竟是什麼,但我所有的System.out打印到該程序的該部分...

在此先感謝您的幫助!

回答

4

首先 你逝去的是有空格,這將打破網址查詢字符串。 Tehrefore,你需要在發送之前執行encode

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

您正在嘗試在UI線程,這將不會在Android中被允許3.0+和將拋出NetworkOnMainThreadException進行網絡操作。使用AsyncTask或單獨的線程來執行網絡操作。

+0

我希望周圍的教程和例子會提到這一點。沒有一個我讀過的例子是在做任何與網絡相關的事情時使用的「AsyncTask」。謝謝。 – nathansizemore 2013-04-29 17:05:34

1
java.lang.IllegalArgumentException: Illegal character in query 

作爲您的獲取請求中的一個字符,在URL中不合法。在GET請求中傳遞它們之前,您必須先對URL進行編碼。有關詳細信息,請參閱:

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

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(); 
    } 
} 
+0

感謝您的支持。我將來可以肯定地使用它。 – nathansizemore 2013-04-29 17:00:31

2

嘗試:

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

如果你想使用JSON作爲「GET」(即作爲URL的一部分),那麼你需要的字符串編碼。例如,請注意,當您在瀏覽器中輸入空白時,它會將其轉換爲%20。這是因爲url不能包含空格。

檢查這個職位如何編碼您的網址: Java URL encoding of query string parameters

1

LogCat輸出顯示您嘗試用於GET請求的requestLink字符串中的一些空格。這是LogCat的相關位

package= { 

您看到等號和開口大括號之間的空格嗎?

您應該在將JSON字符串連接到基本URL之前修剪空白空間。您還應該考慮使用Uri解析方法來確保所有字符編碼正確,http://developer.android.com/reference/android/net/Uri.html#parse(java.lang.String)

最後,你確定你想追加一個大的JSON字符串到基地網址嗎?這似乎有點奇怪,但如果API要求它,上述建議應該解決您的問題。

+0

我真的不想用它作爲'GET'。我寧願使用'POST',但無法真正找到一個體面的教程。現在我已經有了'GET'工作,一旦找到一個體面的教程,找出'POST'的東西就會更容易 – nathansizemore 2013-04-29 17:02:36