android与服务器交互总结(json,post,xUtils,Volley,Gson)

转载请注明:http://blog.csdn.net/u012975370/article/details/46981823

(最后一次更新2016 - 12 - 21)

更新内容:由于android 6.0完全抛弃了HttpClinet,所以,原生的网络请求,建议使用HttpURLConnection,本文的第三方框架,都是去年比较老的,现在xutils都更新到xutils3了,没有大文件的网络请求,使用volley就够了,最近的网络框架有Retrofit和OkHttp等,都是风生水起,建议使用去github搜索框架,百度谷歌使用方法,本次更新了HttpURLConnection的请求使用以及Gson的解析方法。写了一个工具类,凑合看吧


从无到有,从来没有接触过Json,以及与服务器的交互。然后慢慢的熟悉,了解了一点。把我学到的东西简单的做个总结,也做个记录,万一以后用到,就不用到处找了。


主要是简单的数据交互,就是字符串的交互,传数据,取数据。刚开始用的普通方法,后来研究了下xUtils框架。

服务器端有人开发,这一块不是我负责,所以我只负责客户端传数据以及接受数据后的处理就OK了。


传递数据的形式,主要是看服务端的接口怎么写,服务器是接受JSON字符串,还是要form表单格式(我认为form表单格式就是键值对)。


xUtils:

不需要关联library,就下载jar包,复制到libs下就可以了,这是下载地址:http://download.csdn.net/detail/u012975370/9003713

还有就是,你如果想使用library到自己的项目下,注意一点主项目文件和library库文件,必须在同一个文件夹目录下,否则运行项目是报错的

http://blog.csdn.net/dj0379/article/details/38356773

项目原码地址:https://github.com/wyouflf/xUtils

http://www.gbtags.com/gb/share/4360.htm


Volley:

初识Volley的基本用法:http://www.apihome.cn/view-detail-70211.html

使用Volley加载网络图片:http://www.apihome.cn/view-detail-70212.html

定制自己的Request:http://www.apihome.cn/view-detail-70213.html


还有一些框架:KJFeame和Afinal

KJFrame:

http://git.oschina.net/kymjs/KJFrameForAndroid

http://www.codeceo.com/article/android-orm-kjframeforandroid.html


0.HttpUrlConnection的使用

httpUtils工具类下载:https://github.com/NieJianJian/Tools/blob/master/HttpUtil.java

package njj.com.myapplication1;

import android.text.TextUtils;
import android.util.Log;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by jian on 2016/12/15.
 */
public class HttpUtil {

    String Path = "http://test.bidit.cn/api/getServerTime/?clientType=1&version=4&versionName=test_2.0.2";

    /**
     * @param address
     * @param listener
     * @return 将String 改为 void。因为网络请求是耗时操作,我们需要在子线程中执行,
     * 但是子线程无法通过return语句来返回数据,也不能在子线程中更新UI,所以利用回调来实现
     * 除非使用runOnUiThread()方法。
     */
    public static void sendHttpRequest(final String address,
                                       final Map params,
                                       final HttpCallbackListener listener) {
        HttpURLConnection connection = null;
        try {
            URL url = new URL(address);
            connection = (HttpURLConnection) url.openConnection();

            // 请求方式:GET 或者 POST
            connection.setRequestMethod("POST");
            // 设置读取超时时间
            connection.setReadTimeout(5000);
            // 设置连接超时时间
            connection.setConnectTimeout(5000);
            // 接收输入流
            connection.setDoInput(true);
            // 启动输出流,当需要传递参数时开启
            connection.setDoOutput(true);
            /*
             * 添加Header,告诉服务端一些信息,比如读取某个文件的多少字节到多少字节,是不是可以压缩传输,
             * 客户端支持的编码格式,客户端类型,配置,需求等。
             */
//            connection.setRequestProperty("Connection","Keep-Alive"); // 维持长连接
//            connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
            // 添加参数, 写入参数之前不能读取服务器响应,如获得code
            addParams(address, connection.getOutputStream(), params);

            // 发起请求
            connection.connect();

            /**
             * getInputStream实际才发送请求,并得到网络返回的输入流
             */
            InputStream is = connection.getInputStream();
            // 服务器响应code,200表示请求成功并返回
            int code = connection.getResponseCode();
            if (code != HttpURLConnection.HTTP_OK) {
                listener.onError("错误code = " + code);
                return;
            }

            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder response = new StringBuilder();

            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }

            if (listener != null) {
                listener.onSuccess(response.toString());
            }
            /*return response.toString();*/
        } catch (Exception e) {
            e.printStackTrace();
            if (listener != null) {
                listener.onError(e.toString());
            }
            /*return e.getMessage();*/
        } finally {
            if (connection != null) connection.disconnect();
        }
    }

    /**
     * 使用NameValuePair和BasicNameValuePair需要在build.gradle中的android闭包中添加:
     * useLibrary 'org.apache.http.legacy'
     */
    private static void addParams(String address, OutputStream output, Map params)
            throws IOException {
        List paramList = new ArrayList<>();
        for (Map.Entry entry : params.entrySet()) {
            paramList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }

        StringBuilder paramStr = new StringBuilder();
        for (NameValuePair pair : paramList) {
            if (!TextUtils.isEmpty(paramStr)) {
                paramStr.append("&");
            }
            paramStr.append(URLEncoder.encode(pair.getName(), "UTF-8"));
            paramStr.append("=");
            paramStr.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
        }

        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
        // 将参数写入到输出流
        writer.write(paramStr.toString());
        // 刷新对象输出流,将任何字节都写入潜在的流中
        writer.flush();
        // 关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓冲区中,
        // 之后调用的getInputStream()函数时才把准备好的http请求正式发送到服务器
        writer.close();

        /**
         * 打印请求全路径的url
         */
        StringBuilder urlStr = new StringBuilder(address);
        urlStr.append("?");
        urlStr.append(paramStr.toString());
        Log.i("niejianjian", " -> url -> " + urlStr);
    }

    public interface HttpCallbackListener {
        void onSuccess(String response);

        void onError(String errorInfo);
    }

}
使用方式:
package njj.com.myapplication1;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by jian on 2016/12/21.
 */
public class MainActivity extends AppCompatActivity {

    Button mButton;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
//                        String Path = "http://test.bidit.cn/api/sysconfig/Android_minValidVersion/?clientType=1&version=4&versionName=test_2.0.2";
                        String path = "http://test.niejian.cn/api/"; // 假的,并没有这个地址
                        Map params = new HashMap<>();
                        params.put("username", "niejianjian");
                        params.put("password", "123456");
                        HttpUtil.sendHttpRequest(path, params, new HttpUtil.HttpCallbackListener() {
                            @Override
                            public void onSuccess(String response) {
                                Log.i("niejianjian", " -> onSuccess -> " + response);
                            }

                            @Override
                            public void onError(String info) {
                                Log.i("niejianjian", " -> onError -> " + info);
                            }
                        });
                    }
                }).start();
            }
        });

    }
}

下载文件
package preview.ruby.com.myapplication;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.LinearLayout;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class MainActivity extends AppCompatActivity {

    public static final String ROOT_PATH = Environment.getExternalStorageDirectory().toString();
    private static final String PATH = File.separatorChar + "ijizhe";
    private static final String DOWN_URL = "http://download.ijizhe.cn/ijizhe-2.0.6-ijizhe.apk";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        downFile();
                    }
                }).start();

            }
        });

        ((Button) findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                File file = new File(ROOT_PATH + PATH + File.separator + "ijizhe.apk");
                Intent intent1 = new Intent(Intent.ACTION_VIEW);
                // Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
                intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                intent1.setDataAndType(
                        Uri.parse("file://" + ROOT_PATH + PATH + "/ijizhe.apk"),
                        "application/vnd.android.package-archive");
                startActivity(intent1);
            }
        });
    }

    public void downFile() {

        URL url = null;
        try {
            url = new URL(DOWN_URL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //设置超时间为3秒
            conn.setConnectTimeout(3 * 1000);
            //防止屏蔽程序抓取而返回403错误
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            //得到输入流
            InputStream inputStream = conn.getInputStream(); // 发送请求,获得服务器返回的输入流

            //获取自己数组
            byte[] getData = readInputStream(inputStream); // 将请求到的写入到本地,此过程开始耗时。
            Log.i("niejianjian", " -> downFile -> 4 -> " + conn.getResponseCode());
            //文件保存位置
            File saveDir = new File(ROOT_PATH + PATH);
            if (!saveDir.exists()) {
                saveDir.mkdir();
            }
            File file = new File(saveDir + File.separator + "ijizhe.apk");
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(getData);
            if (fos != null) {
                fos.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从输入流中获取字节数组
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

}
添加权限
    
    
    
android6.0需要对STORAGE权限申请运行时权限  :   http://blog.csdn.net/u012975370/article/details/49799041#t33


1.要发送到服务器端的是以JSON字符串的形式发送的。(下面的格式)

{"device":"hwG620S-UL00","brand":"HUAWEI","model":"G620S-UL00","imei":"865242025001258","romversion":"G620S-UL00V100R001C17B264"}

private void sendData1() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				Log.i(TEST_TAG, "2222");
				try {

					HttpPost post = new HttpPost(ACTIVATE_PATH);// post请求
					// 先封装一个JSON对象
					JSONObject param = new JSONObject();
					param.put("romversion", serviceInfoMap.get("romversion"));
					param.put("brand", serviceInfoMap.get("brand"));
					param.put("model", serviceInfoMap.get("model"));
					param.put("device", serviceInfoMap.get("device"));
					param.put("imei", serviceInfoMap.get("imei"));
					// 绑定到请求Entry
					StringEntity se = new StringEntity(param.toString(),
							"utf-8");
					post.setEntity(se);
					Log.i(TEST_TAG, "JSON为---> " + param.toString());
					// JSON为--->
					// {"device":"hwG620S-UL00","brand":"HUAWEI","model":"G620S-UL00","imei":"8					// 65242025001258","romversion":"G620S-UL00V100R001C17B264"}

					// 发送请求
					HttpParams params = new BasicHttpParams();
					DefaultHttpClient localDefaultHttpClient = new DefaultHttpClient(
							params);
					localDefaultHttpClient.getParams().setParameter(
							"http.connection.timeout", Integer.valueOf(30000));
					localDefaultHttpClient.getParams().setParameter(
							"http.socket.timeout", Integer.valueOf(30000));
					HttpResponse response = localDefaultHttpClient
							.execute(post);
					// 得到应答的字符串,这也是一个JSON格式保存的数据
					String retStr = EntityUtils.toString(response.getEntity());
					// 生成JSON对象
					JSONObject result = new JSONObject(retStr);
					int status_value = response.getStatusLine().getStatusCode();
					Log.i(TEST_TAG, "" + status_value);
					String statusValue = "";
					statusValue = result.getString("status");
					Log.i(TEST_TAG, statusValue);
					if (!statusValue.equals("")) {
						// 如果不为空,说明取到了数据,然后就先关闭进去条
						mHandler.sendEmptyMessage(CLOSE_DIALOG);
						// 然后判断值是否==1,来决定弹出哪个dialog
						// 激活成功,就把值传到系统的contentprovider,然后永久保存
						if (Integer.parseInt(statusValue) == 1) {
							mHandler.sendEmptyMessage(SHOW_SUCCESS);
							// 将值设置成1
							Settings.System.putInt(getContentResolver(),
									SETTING_MODIFY_NAME, 1);
						} else { // 只要是不为1外的其他值,都算失败,弹出失败的dialog
							mHandler.sendEmptyMessage(SHOW_FAILURE);
						}
					}

				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				} catch (ClientProtocolException e) {
					e.printStackTrace();
					mHandler.sendEmptyMessage(CONTENT_STATUS);
				} catch (SocketException e) {
					mHandler.sendEmptyMessage(CONTENT_STATUS);
				} catch (IOException e) {
					mHandler.sendEmptyMessage(CONTENT_STATUS);
					e.printStackTrace();
				} catch (JSONException e) {
					mHandler.sendEmptyMessage(CONTENT_STATUS);
					e.printStackTrace();
				}
			}
		}).start();
	}


2.以form表单的格式发送到服务端

将传递的数据打印出来,格式是这样的,和json串是不一样的。[romversion=G620S-UL00V100R001C17B264, brand=HUAWEI, model=G620S-UL00, device=hwG620S-UL00, imei=865242024756522]

private void sendData1() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				Log.i(TEST_TAG, "2222");
				try {

					HttpPost post = new HttpPost(ACTIVATE_PATH);// post请求
					// 设置添加对象
					List paramsForm = new ArrayList();
					paramsForm.add(new BasicNameValuePair("romversion",
							serviceInfoMap.get("romversion")));
					paramsForm.add(new BasicNameValuePair("brand",
							serviceInfoMap.get("brand")));
					paramsForm.add(new BasicNameValuePair("model",
							serviceInfoMap.get("model")));
					paramsForm.add(new BasicNameValuePair("device",
							serviceInfoMap.get("device")));
					paramsForm.add(new BasicNameValuePair("imei",
							serviceInfoMap.get("imei")));
					Log.i(TEST_TAG, paramsForm.toString());
					post.setEntity(new UrlEncodedFormEntity(paramsForm,
							HTTP.UTF_8));

					// 发送请求
					HttpParams params = new BasicHttpParams();
					DefaultHttpClient localDefaultHttpClient = new DefaultHttpClient(
							params);
					localDefaultHttpClient.getParams().setParameter(
							"http.connection.timeout", Integer.valueOf(30000));
					localDefaultHttpClient.getParams().setParameter(
							"http.socket.timeout", Integer.valueOf(30000));
					HttpResponse response = localDefaultHttpClient
							.execute(post);
					// 得到应答的字符串,这也是一个JSON格式保存的数据
					String retStr = EntityUtils.toString(response.getEntity());
					// 生成JSON对象
					JSONObject result = new JSONObject(retStr);
					int status_value = response.getStatusLine().getStatusCode();
					Log.i(TEST_TAG, "" + status_value);
					String statusValue = "";
					statusValue = result.getString("status");
					Log.i(TEST_TAG, "status: " + statusValue);
					Log.i(TEST_TAG, "datatime: " + result.getString("datatime"));
					Log.i(TEST_TAG, "message: " + result.getString("message"));
					if (!statusValue.equals("")) {
						// 如果不为空,说明取到了数据,然后就先关闭进去条
						mHandler.sendEmptyMessage(CLOSE_DIALOG);
						// 然后判断值是否==1,来决定弹出哪个dialog
						// 激活成功,就把值传到系统的contentprovider,然后永久保存
						if (Integer.parseInt(statusValue) == 1) {
							// 将值设置成1。需要加权限
							Settings.System.putInt(getContentResolver(),
									SETTING_MODIFY_NAME, 1);
							mHandler.sendEmptyMessage(SHOW_SUCCESS);
						} else { // 只要是不为1外的其他值,都算失败,弹出失败的dialog
							mHandler.sendEmptyMessage(SHOW_FAILURE);
						}
					}

				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
					mHandler.sendEmptyMessage(SHOW_FAILURE);
					mHandler.sendEmptyMessage(CONTENT_STATUS);
				} catch (ClientProtocolException e) {
					e.printStackTrace();
					mHandler.sendEmptyMessage(SHOW_FAILURE);
					mHandler.sendEmptyMessage(CONTENT_STATUS);
				} catch (SocketException e) {
					mHandler.sendEmptyMessage(SHOW_FAILURE);
					mHandler.sendEmptyMessage(CONTENT_STATUS);
				} catch (IOException e) {
					mHandler.sendEmptyMessage(SHOW_FAILURE);
					mHandler.sendEmptyMessage(CONTENT_STATUS);
					e.printStackTrace();
				} catch (JSONException e) {
					mHandler.sendEmptyMessage(SHOW_FAILURE);
					mHandler.sendEmptyMessage(CONTENT_STATUS);
					e.printStackTrace();
				}
			}
		}).start();
	}


3.xUtils框架的post上传数据,表单格式

/**
	 * 表单格式传送(键值对)
	 */
	private void xUtilsFrame() {
		RequestParams params = new RequestParams();
		params.addBodyParameter("romversion", serviceInfoMap.get("romversion"));
		params.addBodyParameter("brand", serviceInfoMap.get("brand"));
		params.addBodyParameter("model", serviceInfoMap.get("model"));
		params.addBodyParameter("device", serviceInfoMap.get("device"));
		params.addBodyParameter("imei", serviceInfoMap.get("imei"));
		Log.i(TEST_TAG, params.getEntity().toString());

		HttpUtils http = new HttpUtils();
		http.configCurrentHttpCacheExpiry(1000 * 10);
		http.send(HttpMethod.POST, ACTIVATE_PATH, params,
				new RequestCallBack() {

					@Override
					public void onSuccess(ResponseInfo responseInfo) {
						Log.i(TEST_TAG, "接收到的结果为---》" + responseInfo.result);
						Log.i(TEST_TAG, "请求码为--->" + responseInfo.statusCode);
						try {
							JSONObject jsonObject = new JSONObject(
									responseInfo.result);
							Log.i(TEST_TAG, jsonObject.getString("message"));
							if (jsonObject.getString("status").equals("1")) {
								mHandler.sendEmptyMessage(CLOSE_DIALOG);
								mHandler.sendEmptyMessage(SHOW_SUCCESS);
								Settings.System.putInt(getContentResolver(),
										SETTING_MODIFY_NAME, 1);
							} else {
								mHandler.sendEmptyMessage(CLOSE_DIALOG);
								mHandler.sendEmptyMessage(SHOW_FAILURE);
							}
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

					@Override
					public void onFailure(HttpException error, String msg) {
						Toast.makeText(getApplicationContext(), "失败了",
								Toast.LENGTH_LONG).show();
					}
				});
	}

4.xUtils框架,json数据格式

/**
	 * 发送json字符串
	 */
	private void xUtilsFrame2() {
		try {
			RequestParams params = new RequestParams();
			// 先封装一个JSON对象
			JSONObject param = new JSONObject();
			param.put("romversion", serviceInfoMap.get("romversion"));
			param.put("brand", serviceInfoMap.get("brand"));
			param.put("model", serviceInfoMap.get("model"));
			param.put("device", serviceInfoMap.get("device"));
			param.put("imei", serviceInfoMap.get("imei"));
			StringEntity sEntity = new StringEntity(param.toString(), "utf-8");
			params.setBodyEntity(sEntity);
			Log.i(TEST_TAG, "params-->" + params.toString()); // params-->com.lidroid.xutils.http.RequestParams@41c74e10
			Log.i(TEST_TAG, "param-->" + param.toString()); // param-->{"device":"hwG620S-UL00","brand":"HUAWEI","model":"G620S-UL00","imei":"865242024756522","romversion":"G620S-UL00V100R001C17B264"}
			Log.i(TEST_TAG, "param-entity-->" + sEntity.toString()); // param-entity-->org.apache.http.entity.StringEntity@41c482f0

			HttpUtils http = new HttpUtils();
			http.configCurrentHttpCacheExpiry(1000 * 10);
			http.send(HttpMethod.POST, ACTIVATE_PATH, params,
					new RequestCallBack() {

						@Override
						public void onSuccess(ResponseInfo responseInfo) {
							Log.i(TEST_TAG, "接收到的结果为---》" + responseInfo.result); // 接收到的结果为---》{"status":"2","datatime":1437444596,"message":"参数无效!"}
							Log.i(TEST_TAG, "请求码为--->"
									+ responseInfo.statusCode);
							try {
								JSONObject jsonObject = new JSONObject(
										responseInfo.result);
								Log.i(TEST_TAG, jsonObject.getString("message"));
								if (jsonObject.getString("status").equals("1")) {
									mHandler.sendEmptyMessage(CLOSE_DIALOG);
									mHandler.sendEmptyMessage(SHOW_SUCCESS);
									Settings.System.putInt(
											getContentResolver(),
											SETTING_MODIFY_NAME, 1);
								} else {
									mHandler.sendEmptyMessage(CLOSE_DIALOG);
									mHandler.sendEmptyMessage(SHOW_FAILURE);
								}
							} catch (JSONException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}

						@Override
						public void onFailure(HttpException error, String msg) {
							Toast.makeText(getApplicationContext(), "失败了",
									Toast.LENGTH_LONG).show();
						}
					});

		} catch (JSONException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

5.Volley框架:StringRequest,from表单

/**
	 * Volley框架:StirngRequest(需要导入Volley.jar包到libs目录下,需要加internet权限)
	 */
	private void volleyFrameSR() {
		// 第一步:创建一个RequestQueue对象
		final RequestQueue mQueue = Volley.newRequestQueue(this);
		// 第二步:创建一个StringRequest对象
		StringRequest stringRequest = new StringRequest(Method.POST,
				ACTIVATE_PATH, new Response.Listener() {
					// 服务器响应成功的回调
					@Override
					public void onResponse(String response) {
						Log.i(TEST_TAG, "返回结果为--->" + response);
						try {
							JSONObject jsonObject = new JSONObject(response);
							Log.i(TEST_TAG,
									"status-->"
											+ jsonObject.getString("status"));
							Log.i(TEST_TAG,
									"message-->"
											+ jsonObject.getString("message"));
							mQueue.cancelAll("StringRequest");
							mHandler.sendEmptyMessage(SHOW_SUCCESS);
							mHandler.sendEmptyMessage(CLOSE_DIALOG);
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

				}, new Response.ErrorListener() {
					// 服务器响应失败的回调
					@Override
					public void onErrorResponse(VolleyError error) {
						Log.e(TEST_TAG, error.getMessage(), error);
						mHandler.sendEmptyMessage(SHOW_FAILURE);
					}
				}) {

			@Override
			protected Map getParams() throws AuthFailureError {
				Map map = new HashMap();
				map.put("romversion", serviceInfoMap.get("romversion"));
				map.put("brand", serviceInfoMap.get("brand"));
				map.put("model", serviceInfoMap.get("model"));
				map.put("device", serviceInfoMap.get("device"));
				map.put("imei", serviceInfoMap.get("imei"));
				Log.i(TEST_TAG, "发送结果为--->" + map.toString());
				// 发送结果为--->{device=hwG620S-UL00, brand=HUAWEI,
				// model=G620S-UL00, imei=865242024756522,
				// romversion=G620S-UL00V100R001C17B264}

				return map;
			}
		};
		stringRequest.setTag("StringRequest");
		// 第三步:将StringRequest对象添加到RequestQueue里面
		mQueue.add(stringRequest);
	}
这个写了太多的代码,这是方法的原型:

StringRequest stringRequest = new StringRequest(Method.POST, url,  listener, errorListener) {  
    @Override  
    protected Map getParams() throws AuthFailureError {  
        Map map = new HashMap();  
        map.put("params1", "value1");  
        map.put("params2", "value2");  
        return map;  
    }  
};  
根据我服务器的接受模式,我觉得他发送的结果是form表单格式

6.Volley框架: JsonObjectRequest。 

因为它的方法中传递的的请求参数为JsonObject,目前还没有找到传递form格式的方法。

/**
	 * Volley框架:JsonObjectRequest
	 */
	private void volleyFrameJR() {
		// 第一步:创建一个RequestQueue对象
		final RequestQueue mQueue = Volley.newRequestQueue(this);

		JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
				Method.POST, ACTIVATE_PATH, null,
				new Response.Listener() {

					@Override
					public void onResponse(JSONObject response) {
						Log.i(TEST_TAG, "返回结果为--->" + response.toString());
						try {
							// JSONObject jsonObject = new JSONObject(response);
							Log.i(TEST_TAG,
									"status-->" + response.getString("status"));
							Log.i(TEST_TAG,
									"message-->"
											+ response.getString("message"));
							mHandler.sendEmptyMessage(SHOW_SUCCESS);
							mHandler.sendEmptyMessage(CLOSE_DIALOG);
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}, new Response.ErrorListener() {

					@Override
					public void onErrorResponse(VolleyError error) {
						Log.e(TEST_TAG, error.getMessage(), error);
						mHandler.sendEmptyMessage(SHOW_FAILURE);
					}
				}) {
			
			@Override
			protected Map getPostParams()
					throws AuthFailureError {
				Map map = new HashMap();
				map.put("romversion", serviceInfoMap.get("romversion"));
				map.put("brand", serviceInfoMap.get("brand"));
				map.put("model", serviceInfoMap.get("model"));
				map.put("device", serviceInfoMap.get("device"));
				map.put("imei", serviceInfoMap.get("imei"));
				Log.i(TEST_TAG, "发送结果为--->" + map.toString());
				return map;
			}

		};
		mQueue.add(jsonObjectRequest); // 没有这句就无法交互

	}
这种方式应该可以,好像getParams也可以,因为服务器写的不是接受json格式数据,所以我没法测试。

还有就是去掉重写的方法,不管是getPostParams还是getParams,然后将里面的map集合内容写道,new JsonObjectRequest之前,然后在JsonObject  jsonObject = newJsonObject(map),然后将jsonObject作为第三个参数,这样就传递了一个json字符串到服务器。




7.JsonObject和JsonArray

//JsonObject和JsonArray区别就是JsonObject是对象形式,JsonArray是数组形式
        //创建JsonObject第一种方法
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("UserName", "ZHULI");
        jsonObject.put("age", "30");
        jsonObject.put("workIn", "ALI");
        System.out.println("jsonObject1:" + jsonObject);
        
        //创建JsonObject第二种方法
        HashMap hashMap = new HashMap();
        hashMap.put("UserName", "ZHULI");
        hashMap.put("age", "30");
        hashMap.put("workIn", "ALI");
        System.out.println("jsonObject2:" + JSONObject.fromObject(hashMap));
        
        //创建一个JsonArray方法1
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(0, "ZHULI");
        jsonArray.add(1, "30");
        jsonArray.add(2, "ALI");
        System.out.println("jsonArray1:" + jsonArray);
        
        //创建JsonArray方法2
        ArrayList arrayList = new ArrayList();
        arrayList.add("ZHULI");
        arrayList.add("30");
        arrayList.add("ALI");
        System.out.println("jsonArray2:" + JSONArray.fromObject(arrayList));
        
        //如果JSONArray解析一个HashMap,则会将整个对象的放进一个数组的值中
        System.out.println("jsonArray FROM HASHMAP:" + JSONArray.fromObject(hashMap));
        
        //组装一个复杂的JSONArray
        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.put("UserName", "ZHULI");
        jsonObject2.put("age", "30");
        jsonObject2.put("workIn", "ALI");
        jsonObject2.element("Array", arrayList);
        System.out.println("jsonObject2:" + jsonObject2);

system结果:

jsonObject1:{"UserName":"ZHULI","age":"30","workIn":"ALI"}
jsonObject2:{"workIn":"ALI","age":"30","UserName":"ZHULI"}
jsonArray1:["ZHULI","30","ALI"]
jsonArray2:["ZHULI","30","ALI"]
jsonArray FROM HASHMAP:[{"workIn":"ALI","age":"30","UserName":"ZHULI"}]
jsonObject2:{"UserName":"ZHULI","age":"30","workIn":"ALI","Array":["ZHULI","30","ALI"]}
 
  
android读取json数据(遍历JSONObject和JSONArray)
public String getJson(){  
        String jsonString = "{\"FLAG\":\"flag\",\"MESSAGE\":\"SUCCESS\",\"name\":[{\"name\":\"jack\"},{\"name\":\"lucy\"}]}";//json字符串  
        try {  
            JSONObject result = new JSONObject(jsonstring);//转换为JSONObject  
            int num = result.length();  
            JSONArray nameList = result.getJSONArray("name");//获取JSONArray  
            int length = nameList.length();  
            String aa = "";  
            for(int i = 0; i < length; i++){//遍历JSONArray  
                Log.d("debugTest",Integer.toString(i));  
                JSONObject oj = nameList.getJSONObject(i);  
                aa = aa + oj.getString("name")+"|";  
                  
            }  
            Iterator it = result.keys();  
            String aa2 = "";  
            String bb2 = null;  
            while(it.hasNext()){//遍历JSONObject  
                bb2 = (String) it.next().toString();  
                aa2 = aa2 + result.getString(bb2);  
                  
            }  
            return aa;  
        } catch (JSONException e) {  
            throw new RuntimeException(e);  
        }  
    }  


8.生成数组json串

我想要生成的json串为:
{
"languages": [//应用市场所支持的语种信息
  {
"name":"汉语",
"code":"hy",
"selected":"true"
  },
  {
"name":"蒙古语",
"code":"mn"
"selected":"false"
  }
],
"applist_versioncode":"0",
"applist_num":"2",

代码如下:
private void createJsonData() {
		try {
			// 存放总的json数据的容器
			JSONObject jsonObject = new JSONObject();

			/*
			 * 首先,总的josn的第一条的key是languages,他的value是一个数组,数组有两个元素,所以,
			 * languages对应的value是一个JsonArray对象
			 */
			// 此时生成一个jsonarray来存放language的值的数组
			JSONArray jsonArrayLang = new JSONArray();
			// 首先将language的第一条数据,生成jsonObject对象
			JSONObject joLang0 = new JSONObject();
			joLang0.put("name", "汉语");
			joLang0.put("code", "hy");
			joLang0.put("selected", "true");
			// 此时,将数组的第一组数据添加到jsonarray中
			jsonArrayLang.put(0, joLang0);

			// 首先将language的第二条数据,生成jsonObject对象
			JSONObject joLang1 = new JSONObject();
			joLang1.put("name", "蒙古语");
			joLang1.put("code", "mn");
			joLang1.put("selected", "false");
			// 此时,将数组的第一组数据添加到jsonarray中
			jsonArrayLang.put(1, joLang1);

			// 此时,langauge的值已经生成,就是jsonarraylang这个数组格式的数据
			// 然后,将其添加到总的jsonobject中
			jsonObject.put("languages", jsonArrayLang);
			// 添加总jsonobject容器的第二条数据,"applist_versioncode":"0",
			jsonObject.put("applist_versioncode", "0");
			// 添加总jsonobject容器的第三条数据,"applist_num":"2",
			jsonObject.put("applist_num", "2");

			System.out.println(jsonObject.toString());

		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
最后输出结果为


 
  

9.修改json串(带数组)

String stt = "{\"languages\":[{\"name\":\"汉语\",\"code\":\"hy\"},"
			+ "{\"name\":\"蒙古语\",\"code\":\"mn\"}]}";
				try {
					JSONObject jsonObject = new JSONObject(stt);
					System.out.println("修改之前---->" + jsonObject.toString());
					JSONArray jsonArray = jsonObject.getJSONArray("languages");
					System.out.println("修改之前---->" + jsonArray.toString());
					System.out.println("jsonArray.length()---->"
							+ jsonArray.length());
					for (int i = 0; i < jsonArray.length(); i++) {
						JSONObject jsonObject2 = (JSONObject) jsonArray.opt(i);
						System.out.println("jsonObject2---->" + i + "-----"
								+ jsonArray.toString());
						if (i == (jsonArray.length() - 1)) {
							System.out.println("修改之前---->");
							jsonObject2.put("name", "法国与");
							jsonArray.put(i, jsonObject2);
						}
					}
					jsonArray.put(jsonArray.length(),
							(JSONObject) jsonArray.opt(jsonArray.length() - 1));
					jsonObject.put("languages", jsonArray);
					System.out.println("修改之后---->" + jsonObject.toString());
				} catch (JSONException e) {
					e.printStackTrace();
				}
修改json串,就需要一层一层读出来,然后key值存在的时候,直接put新值,就会直接替换掉,然后在一层一层添加回去。这样就可以了



10.Gson解析

首先需要在build.gradle中添加gson依赖

    compile 'com.google.code.gson:gson:2.8.0'
GsonUtils.java

package njj.com.myapplication1;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

/**
 * Created by jian on 2016/12/21.
 */
public class GsonUtils {

    static String response1 = "{\"name\":\"niejian\",\"age\":\"24\"}";
    static String response2 = "{\"bean\":[{\"name\":\"niejian\",\"age\":\"24\"},{\"name\":\"xiaonie\",\"age\":\"20\"},{\"name\":\"xiaojian\",\"age\":\"30\"}]}";

    /**
     * 解析单条数据
     * @return
     */
    public static Bean singleGetResponse() {
//      response1 = {"name":"niejian","age":"24"}
        Gson gson = new Gson();
        Bean bean = gson.fromJson(response1, Bean.class);
        return bean;
    }

    /**
     * 解析多条数据
     * @return
     */
    public static List getResponse() {
//      response2 = {"bean":[{"name":"niejian","age":"24"},{"name":"xiaonie","age":"20"},{"name":"xiaojian","age":"30"}]}
        List beans = null;
        try {
            JSONObject jsonObject = new JSONObject(response2);
            JSONArray jsonArray = jsonObject.getJSONArray("bean");
            Gson gson = new Gson();
            // jsonArray.toString = [{"name":"niejian","age":"24"},{"name":"xiaonie","age":"20"},{"name":"xiaojian","age":"30"}]
            // 参数一传入数组
            beans = gson.fromJson(jsonArray.toString(), new TypeToken>() {
            }.getType());

        } catch (JSONException e) {
            e.printStackTrace();
        }
        return beans;
    }

}

class Bean {
    /**
     * name : niejian
     * age : 24
     */

    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}
 使用方法:

                Bean bean = GsonUtils.singleGetResponse();
                String name = bean.getName();
                String age = bean.getAge();
                Log.i("niejianjian", "neme : " + name + "; age = " + age);

                List beanList = GsonUtils.getResponse();
                for (Bean bean1 : beanList){
                    Log.i("niejianjian", "neme : " + bean1.getName() + "; age = " + bean1.getAge());
                }
就这么简单!!!



参考博客:

android发送/接受json数据:http://407827531.iteye.com/blog/1266217





你可能感兴趣的:(android与服务器交互总结(json,post,xUtils,Volley,Gson))