我在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
都打印到该程序的那一部分......
提前感谢您的帮助!
答案 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编码。有关详细信息,请参阅:
答案 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要求它,上面的建议应该可以解决你的问题。