put-in-a-requesthroughput是什么意思思

1166人阅读
同事今天问我POST和PUT方法的区别,我也不能讲清楚,就去看了下(计算机网络课的参考文献嘛,哈哈)
------------
下面是RFC2616对PUT和POST的区别的阐述:
The fundamental difference between the POST
requests is reflected
in the different meaning of the Request-URI. The URI in a
POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT
request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server&must
not&attempt to apply the request to some other resource. If the server desires that the request be applied to a different URI, it&must&send
the user agent&may&then
make its own decision regarding whether or not to redirect the request.
A single resource&may&be identified by many different URIs. For example, an article might have a URI for identifying &the current version& which is separate from the URI identifying
each particular version. In this case, a PUT request on a general URI might result in several other URIs being defined by the origin server.
可以看出,POST方法和PUT方法的根本区别在于它们的Request-URI含义不同。
我的理解是:
POST方法传递的URI指定了操作资源的的一个程序;而PUT方法则是直接制定了要操作的资源
以上传一张图片为例:
POST(只是指向了mywebsite/upload 这个地址):
HTTP/1.1 PUT /mywebsite/upload/
PUT(直接制定了要操作的资源是.jpg):
HTTP/1.1 PUT /mywebsite/upload/.jpg
另一个重要的区别是,PUT方法是“幂等”的,而POST方法不是。
首先看下RFC2612是怎样定义“幂等(idempotence)”的:
& & & & & & Methods can also have the property of &idempotence& in that (aside from error or expiration issues) the side-effects
of N & 0 identical requests is & & & & & & the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. Also, the methods OPTIONS and TRACE&should
& & & & & & & not&have side effects, and so are inherently idempotent.
也就是,所谓的幂等,就是对请求N次和请求1次的结果是一样的。GET、HEAD、PUT和DELETE都是幂等的,而POST不是。
还是以上传图片为例:
HTTP/1.1 PUT /mywebsite/upload/可能会得到.jpg ,.jpg。。。
HTTP/1.1 PUT /mywebsite/upload/.jpg不论请求多少次都是.jpg (这就是“幂等的”)
版权声明:博客新地址:
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:691607次
积分:9027
积分:9027
排名:第981名
原创:308篇
转载:118篇
评论:329条
(6)(1)(2)(3)(1)(5)(4)(8)(6)(2)(4)(1)(6)(11)(11)(15)(15)(16)(18)(29)(13)(29)(23)(19)(27)(16)(21)(23)(11)(9)(22)(20)(5)(1)(4)(1)(10)(9)详细解读Volley(二)—— ImageRequest & Request简介 - 推酷
详细解读Volley(二)—— ImageRequest & Request简介
上篇文章我们讲到了如何用volley进行简单的网络请求,我们可以很容易的接受到string、JsonObjec类型的返回结果,之前的例子仅仅是一次请求,这里需要说明volley本身就是适合高并发的,所以它可以运行你用volley在短时间内进行多次请求,并且不用去手动管理线程数。仅仅是请求文字过于基础了,本篇将讲述如何用volley从网络下载图片。
一、用ImageRequest来请求图片
ImageRequest是一个图片请求对象,它继承自Request&Bitmap&,所以请求得到的结果是一个bitmap。
1.1 使用步骤
ImageRequest仍旧是一个request对象,所以使用方式和StringRequest、JsonObjectRequest、JsonArrayRequest十分相似。
建立一个RequestQueue对象
建立一个ImageRequest对象
将ImageRequest添加到RequestQueue中
第一步、第三步我们在上篇文章中已经做好了,如果不清楚的话可以去上一篇文章查看。
1.2 分析构造函数
源码中的初始化是这样定义的:
* Creates a new image request, decoding to a maximum specified width and
* height. If both width and height are zero, the image will be decoded to
* its natural size. If one of the two is nonzero, that dimension will be
* clamped and the other one will be set to preserve the image's aspect
* ratio. If both width and height are nonzero, the image will be decoded to
* be fit in the rectangle of dimensions width x height while keeping its
* aspect ratio.
* @param url URL of the image
* @param listener Listener to receive the decoded bitmap
* @param maxWidth Maximum width to decode this bitmap to, or zero for none
* @param maxHeight Maximum height to decode this bitmap to, or zero for
* @param decodeConfig Format to decode the bitmap to
* @param errorListener Error listener, or null to ignore errors
public ImageRequest(String url, Response.Listener&Bitmap& listener, int maxWidth, int maxHeight,
Config decodeConfig, Response.ErrorListener errorListener) {
super(Method.GET, url, errorListener);
setRetryPolicy(
new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT));
mListener =
mDecodeConfig = decodeC
mMaxWidth = maxW
mMaxHeight = maxH
先来解释下注释的意思:
建立一个请求对象,按照最大宽高进行解码 。
如果设定的宽和高都是0,那么下载到的图片将会按照实际的大小进行解码,也就是不压缩。
如果宽和高中的一个或两个值不为0,那么图片的宽/高(取决于你设定了宽还是高)会压缩至设定好的值,而另一个宽/高将会按比例改变。
如果宽和高都不是0,那么就按照你设定的宽高进行解码,显示。
接着解释下代码片段:
public ImageRequest(String url, Response.Listener&Bitmap& listener, int maxWidth, int maxHeight,
Config decodeConfig, Response.ErrorListener errorListener) {
super(Method.GET, url, errorListener);
setRetryPolicy(
new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT));
mListener =
mDecodeConfig = decodeC
mMaxWidth = maxW
mMaxHeight = maxH
默认的请求方式是GET,初始化方法需要传入:图片的url,一个响应结果监听器,图片的最大宽度,图片的最大高度,图片的颜色属性,出错响应的监听器。
说明:图片的颜色属性,Bitmap.Config下的几个常量都可以在这里使用,其中ARGB_8888可以展示最好的颜色属性,每个图片像素占据4个字节的大小,而RGB_565则表示每个图片像素占据2个字节大小
/** Socket timeout in milliseconds for image requests */
private static final int IMAGE_TIMEOUT_MS = 1000;
/** Default number of retries for image requests */
private static final int IMAGE_MAX_RETRIES = 2;
/** Default backoff multiplier for image requests */
private static final float IMAGE_BACKOFF_MULT = 2f;
设定超时时间:1000ms;
最大的请求次数:2次;
发生冲突时的重传延迟增加数:2f(这个应该和TCP协议有关,冲突时需要退避一段时间,然后再次请求);
其余的代码我们就不看了,直接看如何初始化。
1.3 初始化对象并使用
ImageRequest imageRequest = new ImageRequest(
&/uploads/item//44_MBEmX.jpeg&,
new ResponseListener(),
0, // 图片的宽度,如果是0,就不会进行压缩,否则会根据数值进行压缩
0, // 图片的高度,如果是0,就不进行压缩,否则会压缩
Config.ARGB_8888, // 图片的颜色属性
new ResponseErrorListener());
private class ResponseListener implements Response.Listener&Bitmap& {
public void onResponse(Bitmap response) {
Log.d(&TAG&, &-------------\n& + response.toString());
iv.setImageBitmap(response);
private class ResponseErrorListener implements Response.ErrorListener {
public void onErrorResponse(VolleyError error) {
Log.e(&TAG&, error.getMessage(), error);
最后将其添加到请求队列即可:
mQueue.add(imageRequest);
1.4 & 题外话
这样我们就用volley获得了网络图片,代码也十分简单。你可能会说,有没有其他的,更好的方式来获取图片呢?当然有的,比如volley还提供了ImageLoader、NetworkImageView这样的对象,它们可以更加方便的获取图片。值得一提的是这两个对象的内部都是使用了ImageRequest进行操作的,也就是说imageRequest是本质,这也就是为啥我专门写一篇来分析ImageRequest的原因。
说话要言之有理,所以贴上ImageLoader、NetworkImageView源码中部分片段来证明其内部确实是用了ImageRequest。
ImageLoader的源码片段:
public ImageContainer get(String requestUrl, ImageListener imageListener,
int maxWidth, int maxHeight) {
// ………// The request is not already in flight. Send the new request to the network and
// track it.
Request&Bitmap& newRequest = makeImageRequest(requestUrl, maxWidth, maxHeight, cacheKey);
newRequest.setShouldCache(mShouldCache);
mRequestQueue.add(newRequest);
mInFlightRequests.put(cacheKey,
new BatchedImageRequest(newRequest, imageContainer));
return imageC
protected Request&Bitmap& makeImageRequest(String requestUrl, int maxWidth, int maxHeight, final String cacheKey) {
return new ImageRequest(requestUrl, new Listener&Bitmap&() {
public void onResponse(Bitmap response) {
onGetImageSuccess(cacheKey, response);
}, maxWidth, maxHeight,
Config.RGB_565, new ErrorListener() {
public void onErrorResponse(VolleyError error) {
onGetImageError(cacheKey, error);
NetworkImageView的源码片段:
public void setImageUrl(String url, ImageLoader imageLoader) {
mImageLoader = imageL
// The URL has potentially changed. See if we need to load it.
loadImageIfNecessary(false);
它本身就调用的是ImageLoader对象,所以自然也是用到了ImageRequest。
二、 Request简介
Request是Volley中最最核心的类,之前讲到的对象都是它的子类。从字面意思看,这个对象是用来执行请求的,但通过之前的使用我们发现,它还做了很多别的事情。先贴一个Request的子类。
ImageRequest imageRequest = new ImageRequest(
&/uploads/item//44_MBEmX.jpeg&,
new ResponseListener(),
0, // 图片的宽度,如果是0,就不会进行压缩,否则会根据数值进行压缩
0, // 图片的高度,如果是0,就不进行压缩,否则会压缩
Config.ARGB_8888, // 图片的颜色属性
new ResponseErrorListener());
从中我们可以发现这个ImageRequest中传入了请求的url,毕竟是request嘛,请求的url是必须的,但我们还发现这个请求对象还处理了两个监听器,这就说明它不仅仅做了请求,同时对于响应的结果也做了分发处理。
2.2 部分API
getCacheKey()
Returns the cache key for this request. By default, this is the URL.
返回这个请求对象中缓存对象的key,默认返回的是请求的URL
getBodyContentType()
Returns the content type of the POST or PUT body.
返回POST或PUT请求内容的类型,我测试的结果是:
application/x-www-form- charset=UTF-8
从源码就能看出,默认的编码方式是UTF-8:
* Default encoding for POST or PUT parameters. See {@link #getParamsEncoding()}.
private static final String DEFAULT_PARAMS_ENCODING = &UTF-8&;
* Returns the content type of the POST or PUT body.
public String getBodyContentType() {
return &application/x-www-form- charset=& + getParamsEncoding();
getSequence()
Returns the sequence number of this request.
返回请求的序列数
Returns the URL of this request.
返回请求的URL
setShouldCache(boolean bl)
Set whether or not responses to this request should be cached.
设置这个请求是否有缓存,这个缓存是磁盘缓存,和内存缓存没什么事情,默认是true,也就是说如果你不设置为false,这个请求就会在磁盘中进行缓存。其实,之前讲的的StringRequest,JsonRequest,ImageRequest得到的数据都会被缓存,无论是Json数据,还是图片都会自动的缓存起来。然而,一旦你设置setShouldCache(false),这些数据就不会被缓存了。
Returns the raw POST or PUT body to be sent.
返回POST或PUT的请求体
deliverError()
分发错误信息,这个就是调用监听器的方法,贴源码就明白了。
* Delivers error message to the ErrorListener that the Request was
* initialized with.
* @param error Error details
public void deliverError(VolleyError error) {
if (mErrorListener != null) {
mErrorListener.onErrorResponse(error);
setRetryPolicy(RetryPolicy retryPolicy)
对一个request的重新请求策略的设置,不同的项目是否需要重新请求,重新请求几次,请求超时的时间,这些就在这设置到里面。
* Sets the retry policy for this request.
* @return This Request object to allow for chaining.
public Request&?& setRetryPolicy(RetryPolicy retryPolicy) {
mRetryPolicy = retryP
return this;
从上面的源码可以看出,这里需要传入一个RetryPlicy的子类,就是重新请求策略的子类,Volley会在构造Request时传一个默认的对象,叫做DefaultRetryPolicy。
* Creates a new request with the given method (one of the values from {@link Method}),
* URL, and error listener.
Note that the normal response listener is not provided here as
* delivery of responses is provided by subclasses, who have a better idea of how to deliver
* an already-parsed response.
public Request(int method, String url, Response.ErrorListener listener) {
mErrorListener =
setRetryPolicy(new DefaultRetryPolicy());
mDefaultTrafficStatsTag = findDefaultTrafficStatsTag(url);
如果你对于网络请求有具体的要求,可以实现RetryPolicy接口,进行自由的配置。下面贴一下DefaultRetryPolicy源码,方便参考。
* Copyright (C) 2011 The Android Open Source Project
* Licensed under the Apache License, Version 2.0 (the &License&);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an &AS IS& BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
package com.android.
* Default retry policy for requests.
public class DefaultRetryPolicy implements RetryPolicy {
/** The current timeout in milliseconds. */
private int mCurrentTimeoutMs;
/** The current retry count. */
private int mCurrentRetryC
/** The maximum number of attempts. */
private final int mMaxNumR
/** The backoff multiplier for the policy. */
private final float mBackoffM
/** The default socket timeout in milliseconds */
public static final int DEFAULT_TIMEOUT_MS = 2500;
/** The default number of retries */
public static final int DEFAULT_MAX_RETRIES = 1;
/** The default backoff multiplier */
public static final float DEFAULT_BACKOFF_MULT = 1f;
* Constructs a new retry policy using the default timeouts.
public DefaultRetryPolicy() {
this(DEFAULT_TIMEOUT_MS, DEFAULT_MAX_RETRIES, DEFAULT_BACKOFF_MULT);
* Constructs a new retry policy.
* @param initialTimeoutMs The initial timeout for the policy.
* @param maxNumRetries The maximum number of retries.
* @param backoffMultiplier Backoff multiplier for the policy.
public DefaultRetryPolicy(int initialTimeoutMs, int maxNumRetries, float backoffMultiplier) {
mCurrentTimeoutMs = initialTimeoutMs;
mMaxNumRetries = maxNumR
mBackoffMultiplier = backoffM
* Returns the current timeout.
public int getCurrentTimeout() {
return mCurrentTimeoutMs;
* Returns the current retry count.
public int getCurrentRetryCount() {
return mCurrentRetryC
* Returns the backoff multiplier for the policy.
public float getBackoffMultiplier() {
return mBackoffM
* Prepares for the next retry by applying a backoff to the timeout.
* @param error The error code of the last attempt.
public void retry(VolleyError error) throws VolleyError {
mCurrentRetryCount++;
mCurrentTimeoutMs += (mCurrentTimeoutMs * mBackoffMultiplier);
if (!hasAttemptRemaining()) {
* Returns true if this policy has attempts remaining, false otherwise.
protected boolean hasAttemptRemaining() {
return mCurrentRetryCount &= mMaxNumR
2.3 产生Request对象
虽然我们在代码中都会初始化一个Request对象,但是我们要在把他添加到响应队列中后才能得到它的完整体。
public &T& Request&T& add(Request&T& request) {
com.android.volley.Request&Bitmap& bitmapRequest = mQueue.add(imageRequest);
说明:如果你要设定这个request是不需要进行磁盘缓存的,那么请在把它添加到响应队列之前就进行设置,否则会得到不想要的效果。原因:源码在添加队列时会判断是否需要缓存。
* Adds a Request to the dispatch queue.
* @param request The request to service
* @return The passed-in request
public &T& Request&T& add(Request&T& request) {
// Tag the request as belonging to this queue and add it to the set of current requests.
request.setRequestQueue(this);
synchronized (mCurrentRequests) {
mCurrentRequests.add(request);
// Process requests in the order they are added.
request.setSequence(getSequenceNumber());
request.addMarker(&add-to-queue&);
// If the request is uncacheable, skip the cache queue and go straight to the network.
if (!request.shouldCache()) {
mNetworkQueue.add(request);
return request; // 如果不需要缓存,直接返回request对象,不会执行下面的代码
// Insert request into stage if there's already a request with the same cache key in flight.
synchronized (mWaitingRequests) {
String cacheKey = request.getCacheKey();
if (mWaitingRequests.containsKey(cacheKey)) {
// There is already a request in flight. Queue up.
Queue&Request&?&& stagedRequests = mWaitingRequests.get(cacheKey);
if (stagedRequests == null) {
stagedRequests = new LinkedList&Request&?&&();
stagedRequests.add(request);
mWaitingRequests.put(cacheKey, stagedRequests);
if (VolleyLog.DEBUG) {
VolleyLog.v(&Request for cacheKey=%s is in flight, putting on hold.&, cacheKey);
// Insert 'null' queue for this cacheKey, indicating there is now a request in
// flight.
mWaitingRequests.put(cacheKey, null);
mCacheQueue.add(request);
已发表评论数()
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
排版有问题
没有分页内容
视频无法显示
图片无法显示

我要回帖

更多关于 put on是什么意思 的文章

 

随机推荐