Volley和网络数据通信工作总结

1. put、get、post和delete

    他们是与服务器交互的方法。post、delete、put、get分别对应HTTP协议中的增删改查四种操作行为。

  1.1 get和post的区别

    这两者都是发送数据并返回数据。只是get是发送索引去获取服务器内容,而post是发送内容获取服务器的反馈。Rest模式get,put,post,delete含义与区别(转)这篇Blog着重分析了get和post的区别。


2. 错误返回码

    网络请求发生错误就会返回一个错误码,如我们常见的404.下面就是HTTP中的一些错误返回码,红色标注的是我在工作中遇到的错误码。

 400 - 错误的请求。
·401 - 访问被拒绝。IIS定义了许多不同的 401 错误,它们指明更为具体的错误原因。这些具体的错误代码在浏览器中显示,但不在IIS日志中显示: ·401.1 - 登录失败。
·401.2 - 服务器配置导致登录失败。
·401.3 - 由于ACL对资源的限制而未获得授权。
·401.4 - 筛选器授权失败。
·401.5 - ISAPI/CGI应用程序授权失败。
·401.7 – 访问被 Web 服务器上的URL授权策略拒绝。这个错误代码为IIS 6.0 所专用。
·403 - 禁止访问:IIS 定义了许多不同的 403 错误,它们指明更为具体的错误原因: ·403.1 - 执行访问被禁止。
·403.2 - 读访问被禁止。
·403.3 - 写访问被禁止。
·403.4 - 要求 SSL。
·403.5 - 要求 SSL 128。
·403.6 - IP地址被拒绝。
·403.7 - 要求客户端证书。
·403.8 - 站点访问被拒绝。
·403.9 - 用户数过多。
·403.10 - 配置无效。
·403.11 - 密码更改。
·403.12 - 拒绝访问映射表。
·403.13 - 客户端证书被吊销。
·403.14 - 拒绝目录列表。
·403.15 - 超出客户端访问许可。
·403.16 - 客户端证书不受信任或无效。
·403.17 - 客户端证书已过期或尚未生效。
·403.18 - 在当前的应用程序池中不能执行所请求的URL。这个错误代码为 IIS 6.0 所专用。
·403.19 - 不能为这个应用程序池中的客户端执行CGI。这个错误代码为 IIS 6.0 所专用。
·403.20 - Passport 登录失败。这个错误代码为 IIS 6.0 所专用。
·404 - 未找到。 ·404.0 -(无) – 没有找到文件或目录。
·404.1 - 无法在所请求的端口上访问 Web 站点。
·404.2 - Web 服务扩展锁定策略阻止本请求。
·404.3 - MIME 映射策略阻止本请求。
·405 - 用来访问本页面的 HTTP 谓词不被允许(方法不被允许)
·406 - 客户端浏览器不接受所请求页面的 MIME 类型。
·407 - 要求进行代理身份验证。
·412 - 前提条件失败。
·413 – 请求实体太大。
·414 - 请求 URI 太长。
·415 – 不支持的媒体类型。
·416 – 所请求的范围无法满足。
·417 – 执行失败。
·423 – 锁定的错误。

3. volley的get方法的简单使用

    get方法是最简单的请求方法,只要有url,在url后面拼接请求的字符,使用volley直接请求即可获取数据。

String url = "";
RequestQueue requestQueue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        //成功返回数据
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        //返回错误信息
    }
});
requestQueue.add(stringRequest);

    在浏览器上输入的url都是以get方法来获取的数据。

    get字段的拼接:域名?key=value&key=value&key=value


4. volley的post方法的学习研究

    当我们需要往服务器中发送内容时,我们使用post或put方法

    这里有两种post传递json格式数据到服务器的方法

  4.1 在JsonObjectRequest中传入定义好的JsonObject

String url = "";
JSONObject requestBody = new JSONObject();
try {
    requestBody.put("key","value");
} catch (JSONException e) {
    e.printStackTrace();
}
RequestQueue requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, requestBody, new Response.Listener<JSONObject>() {
    @Override
    public void onResponse(JSONObject response) {

    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {

    }
});
requestQueue.add(jsonObjectRequest);
  4.2 重写getParams方法

String url = "";
RequestQueue requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, new Response.Listener<JSONObject>() {
    @Override
    public void onResponse(JSONObject response) {

    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {

    }
}){
    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        Map<String, String> map = new HashMap<>();
        map.put("key", "value");
        return map;
    }
};
requestQueue.add(jsonObjectRequest);
  4.3 对比结果:两个方法是一样的

    这两种方法看着不同,其实是一个东东。看了volley源码发现这两个值最后都会到getBody方法中

@Override
public byte[] getBody() {
    try {
        return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET);
    } catch (UnsupportedEncodingException uee) {
        VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
                mRequestBody, PROTOCOL_CHARSET);
        return null;
    }
}
    这里的mRequestBody就是我们传入的jsonObject。而在另一边:

public byte[] getBody() throws AuthFailureError {
    Map<String, String> params = getParams();
    if (params != null && params.size() > 0) {
        return encodeParameters(params, getParamsEncoding());
    }
    return null;
}
    也就是说,两者都会被getBody方法使用,而优先级是传入JsonObject要比重写getParams方法高。

    另外看到网上有说重写getBody、getPostBody方法传参,其实执行的都是获取body行为。

5. 使用volley实现以put方法推送消息到服务器

    研究两天成功将数据以put方法推送的服务器,代码如下:

RequestQueue requestQueue = Volley.newRequestQueue(context);
String url = "";
StringRequest stringRequest = new StringRequest(Request.Method.PUT, url, new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        LogUtil.e("获取成功=" + response);
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        LogUtil.e("获取失败=" + error);
    }
}) {
    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        Map<String, String> map = new HashMap<>();
        map.put("key", "value");
        return map;
    }
};
requestQueue.add(stringRequest);
             使用方法实测和post的用法是一样的,只是想method改成了put。

6. Volley单例工具类

    为了防止请求队列RequestQueue对象被多次重复创建,不必要的耗费手机资源。Google建议使用Volley单例工具类。

工具类代码(参考 Android Volley框架使用详解):

/**
 * Volley单例工具
 */
public class VolleySingleton {
    private static VolleySingleton volleySingleton;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private Context mContext;

    public VolleySingleton(Context context) {
        this.mContext = context;
        mRequestQueue = getRequestQueue();
        mImageLoader = new ImageLoader(mRequestQueue,
                new ImageLoader.ImageCache(){
                    private final LruCache<String,Bitmap> cache = new LruCache<String ,Bitmap>(20);
                    @Override
                    public Bitmap getBitmap(String url){
                        return cache.get(url);
                    }
                    @Override
                    public void putBitmap(String url,Bitmap bitmap){
                        cache.put(url,bitmap);
                    }
                });
    }

    public static synchronized VolleySingleton getVolleySingleton(Context context){
        if(volleySingleton == null){
            volleySingleton = new VolleySingleton(context);
        }
        return volleySingleton;
    }

    public RequestQueue getRequestQueue(){
        if(mRequestQueue == null){
            mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
        }
        return mRequestQueue;
    }

    /**
     * 添加到请求队列
     * @param req
     * @param <T>
     */
    public <T> void addToRequestQueue(Request<T> req){
        getRequestQueue().add(req);
    }

    public ImageLoader getImageLoader() {
        return mImageLoader;
    }
}

   

7. 对Volley的封装

        在工作中发现对于自己的业务逻辑,可以对代码进行封装。

public class VolleyModel {

    private static final String TAG = "Volley Model";
    public static Gson gson = new Gson();

    public static void volleyGet(String url, final Context context, final VolleyResult volleyResult) {
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                String result = response.replace("\\", "").substring(1, response.replace("\\", "").length() - 1);
                LogUtil.e(TAG + " 获取成功=" + result);
                if (result.contains("ERROR")) {
                    Error error = gson.fromJson(result, Error.class);
                    ToastUtil.showToast(context, error.getMsg());
                } else {
                    volleyResult.onSuccess(result, gson);
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                LogUtil.e(TAG + " 获取失败=" + error);
                volleyResult.onFail(error);
            }
        });
        VolleySingletonUtil.getVolleySingleton(context.getApplicationContext()).addToRequestQueue(stringRequest);
    }

    public static void volleyUpload(String url, int type, final Context context, final Map<String, String> map, final VolleyResult volleyResult){
        StringRequest stringRequest = new StringRequest(type, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                String result = response.replace("\\", "").substring(1, response.replace("\\", "").length() - 1);
                LogUtil.e(" 获取成功=" + result);
                if (result.contains("ERROR")) {
                    Error error = gson.fromJson(result, Error.class);
                    ToastUtil.showToast(context, error.getMsg());
                } else {
                    volleyResult.onSuccess(result, gson);
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                LogUtil.e(" 获取失败=" + error);
                ToastUtil.showToast(context, R.string.toast_connect_fail);
                volleyResult.onFail(error);
            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                return map;
            }
        };
        VolleySingletonUtil.getVolleySingleton(context.getApplicationContext()).addToRequestQueue(stringRequest);
    }

}
在服务器返回结果中存在ERROR的时候gson解析为错误对象、否则解析为正确的数据对象。

8. 一些心得

    Volley可以胜任大多数的网络通信行为,少数无法实现的网络行为,可以通过重写volley来实现(当然,这个还没深究过);

    在浏览器中的输入的url都是get方式获取的数据;

    get、post、put都是发送数据并返回数据,只是用途不同;

    在url地址后面加上各个字段可以是用get直接拼接实现,也可以将后面的拼接字段放在post里面去发送,当然,使用get才是正解,post大多时候还是用来像服务器推送数据而非发送索引字段的。

    volley中可以用到匿名方法getParams,getBody,getHeader这些方法来实现一些特殊需求。

             当出现404、405、400等错误时,说明服务端有问题,多与服务器后端开发人员扯皮。

PS:服务器和HTTP的知识还需要多了解才是。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值