Volley框架源码修改,添加头部验证Hreaders问题

应项目要求修改网络问题,为了让项目更加健壮,使用Volley框架,这个android 推荐使用的网络框架,整体来说请求的方式网上都可以查的到,这里就不说,现在就说说添加头部验证,因为我们的项目在请求每一个链接的时候都会验证,所以添加头部是一个十分必要的情况。网上说让在请求里边添加getHeaders()方法,方法是确实能用,但是是有前提的。

主要是使用不同的队列的问题:

    (1)Volley.newRequestQueue(this)

        如果是调用这个方法的话,那么在执行StringRequest方法的时候调用的HttpClientStack  这个类中的访问网络的方法:

/*
 * 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.volley.toolbox;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Request.Method;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * An HttpStack that performs request over an {@link HttpClient}.
 */
public class HttpClientStack implements HttpStack {
    protected final HttpClient mClient;

    private final static String HEADER_CONTENT_TYPE = "Content-Type";

    public HttpClientStack(HttpClient client) {
        mClient = client;
    }

    private static void addHeaders(HttpUriRequest httpRequest, Map<String, String> headers) {
        for (String key : headers.keySet()) {
            httpRequest.setHeader(key, headers.get(key));
        }
    }

    @SuppressWarnings("unused")
    private static List<NameValuePair> getPostParameterPairs(Map<String, String> postParams) {
        List<NameValuePair> result = new ArrayList<NameValuePair>(postParams.size());
        for (String key : postParams.keySet()) {
            result.add(new BasicNameValuePair(key, postParams.get(key)));
        }
        return result;
    }

    @Override
    public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
            throws IOException, AuthFailureError {
        HttpUriRequest httpRequest = createHttpRequest(request, additionalHeaders);
        addHeaders(httpRequest, additionalHeaders);
        addHeaders(httpRequest, request.getHeaders());
        onPrepareRequest(httpRequest);
        HttpParams httpParams = httpRequest.getParams();
        int timeoutMs = request.getTimeoutMs();
        // TODO: Reevaluate this connection timeout based on more wide-scale
        // data collection and possibly different for wifi vs. 3G.
        HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
        HttpConnectionParams.setSoTimeout(httpParams, timeoutMs);
        return mClient.execute(httpRequest);
    }

    /**
     * Creates the appropriate subclass of HttpUriRequest for passed in request.
     */
    @SuppressWarnings("deprecation")
    /* protected */ static HttpUriRequest createHttpRequest(Request<?> request,
            Map<String, String> additionalHeaders) throws AuthFailureError {
        switch (request.getMethod()) {
            case Method.DEPRECATED_GET_OR_POST: {
                // This is the deprecated way that needs to be handled for backwards compatibility.
                // If the request's post body is null, then the assumption is that the request is
                // GET.  Otherwise, it is assumed that the request is a POST.
                byte[] postBody = request.getPostBody();
                if (postBody != null) {
                    HttpPost postRequest = new HttpPost(request.getUrl());
                    postRequest.addHeader(HEADER_CONTENT_TYPE, request.getPostBodyContentType());
                    postRequest.setHeader("Authorization","Basic YW5vbnltb3VzOjEyMzQ1Ng==");
                    HttpEntity entity;
                    entity = new ByteArrayEntity(postBody);
                    postRequest.setEntity(entity);
                    return postRequest;
                } else {
                    return new HttpGet(request.getUrl());
                }
            }
            case Method.GET:
            HttpGet  httpGet  =new HttpGet(request.getUrl());
//             httpGet.setHeader("Authorization","Basic YW5vbnltb3VzOjEyMzQ1Ng==");
                return httpGet;
            case Method.DELETE:
            HttpDelete  httpDelete =new HttpDelete(request.getUrl());
                return new HttpDelete(request.getUrl());
            case Method.POST: {
                HttpPost postRequest = new HttpPost(request.getUrl());
                postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
                setEntityIfNonEmptyBody(postRequest, request);
                return postRequest;
            }
            case Method.PUT: {
                HttpPut putRequest = new HttpPut(request.getUrl());
                putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
                setEntityIfNonEmptyBody(putRequest, request);
                return putRequest;
            }
            default:
                throw new IllegalStateException("Unknown request method.");
        }
    }

    private static void setEntityIfNonEmptyBody(HttpEntityEnclosingRequestBase httpRequest,
            Request<?> request) throws AuthFailureError {
        byte[] body = request.getBody();
        if (body != null) {
            HttpEntity entity = new ByteArrayEntity(body);
            httpRequest.setEntity(entity);
        }
    }

    /**
     * Called before the request is executed using the underlying HttpClient.
     *
     * <p>Overwrite in subclasses to augment the request.</p>
     */
    protected void onPrepareRequest(HttpUriRequest request) throws IOException {
        // Nothing.
    }
}

可以看到,这个里边是使用了HttpClient    来进行访问网络,但是再他设置访问方式的时候没有调用getHeaders这个方法

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
// headers.put("Charset", "UTF-8");
// headers.put("Content-Type", "application/x-javascript");
// headers.put("Accept-Encoding", "gzip,deflate");
headers.put("Authorization", "Basic YW5vbnltb3VzOjEyMzQ1Ng==");
return headers;
}

//设置超时
public RetryPolicy getRetryPolicy() {
RetryPolicy retryPolicy = new DefaultRetryPolicy(1000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
return retryPolicy;
}

     也就不会添加你设置的头部,那么访问肯定通不过。

所以你可以再里边给添加你的头部,或是,在里边调用getHeaders方法,把头部添加到相应的请求里。

(2) Volley.newRequestQueue(this,new HurlStack())

       这个创建的队列他在执行的时候调用的是HttpUrlConnition   这种访问网络的方式,

/*
 * 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.volley.toolbox;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Request.Method;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.StatusLine;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;

/**
 * An {@link HttpStack} based on {@link HttpURLConnection}.
 */
public class HurlStack implements HttpStack {

    private static final String HEADER_CONTENT_TYPE = "Content-Type";

    /**
     * An interface for transforming URLs before use.
     */
    public interface UrlRewriter {
        /**
         * Returns a URL to use instead of the provided one, or null to indicate
         * this URL should not be used at all.
         */
        public String rewriteUrl(String originalUrl);
    }

    private final UrlRewriter mUrlRewriter;
    private final SSLSocketFactory mSslSocketFactory;

    public HurlStack() {
        this(null);
    }

    /**
     * @param urlRewriter Rewriter to use for request URLs
     */
    public HurlStack(UrlRewriter urlRewriter) {
        this(urlRewriter, null);
    }

    /**
     * @param urlRewriter Rewriter to use for request URLs
     * @param sslSocketFactory SSL factory to use for HTTPS connections
     */
    public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory) {
        mUrlRewriter = urlRewriter;
        mSslSocketFactory = sslSocketFactory;
    }

    @Override
    public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
            throws IOException, AuthFailureError {
        String url = request.getUrl();
        HashMap<String, String> map = new HashMap<String, String>();
        map.putAll(request.getHeaders());
        map.putAll(additionalHeaders);
        if (mUrlRewriter != null) {
            String rewritten = mUrlRewriter.rewriteUrl(url);
            if (rewritten == null) {
                throw new IOException("URL blocked by rewriter: " + url);
            }
            url = rewritten;
        }
        URL parsedUrl = new URL(url);
        HttpURLConnection connection = openConnection(parsedUrl, request);
        for (String headerName : map.keySet()) {
            connection.addRequestProperty(headerName, map.get(headerName));
        }
        setConnectionParametersForRequest(connection, request);
        // Initialize HttpResponse with data from the HttpURLConnection.
        ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);
        int responseCode = connection.getResponseCode();
        if (responseCode == -1) {
            // -1 is returned by getResponseCode() if the response code could not be retrieved.
            // Signal to the caller that something was wrong with the connection.
            throw new IOException("Could not retrieve response code from HttpUrlConnection.");
        }
        StatusLine responseStatus = new BasicStatusLine(protocolVersion,
                connection.getResponseCode(), connection.getResponseMessage());
        BasicHttpResponse response = new BasicHttpResponse(responseStatus);
        response.setEntity(entityFromConnection(connection));
        for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
            if (header.getKey() != null) {
                Header h = new BasicHeader(header.getKey(), header.getValue().get(0));
                response.addHeader(h);
            }
        }
        return response;
    }

    /**
     * Initializes an {@link HttpEntity} from the given {@link HttpURLConnection}.
     * @param connection
     * @return an HttpEntity populated with data from <code>connection</code>.
     */
    private static HttpEntity entityFromConnection(HttpURLConnection connection) {
        BasicHttpEntity entity = new BasicHttpEntity();
        InputStream inputStream;
        try {
            inputStream = connection.getInputStream();
        } catch (IOException ioe) {
            inputStream = connection.getErrorStream();
        }
        entity.setContent(inputStream);
        entity.setContentLength(connection.getContentLength());
        entity.setContentEncoding(connection.getContentEncoding());
        entity.setContentType(connection.getContentType());
        return entity;
    }

    /**
     * Create an {@link HttpURLConnection} for the specified {@code url}.
     */
    protected HttpURLConnection createConnection(URL url) throws IOException {
        return (HttpURLConnection) url.openConnection();
    }

    /**
     * Opens an {@link HttpURLConnection} with parameters.
     * @param url
     * @return an open connection
     * @throws IOException
     */
    private HttpURLConnection openConnection(URL url, Request<?> request) throws IOException {
        HttpURLConnection connection = createConnection(url);

        int timeoutMs = request.getTimeoutMs();
        connection.setConnectTimeout(timeoutMs);
        connection.setReadTimeout(timeoutMs);
        connection.setUseCaches(false);
        connection.setDoInput(true);

        // use caller-provided custom SslSocketFactory, if any, for HTTPS
        if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) {
            ((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
        }

        return connection;
    }

    @SuppressWarnings("deprecation")
    /* package */ static void setConnectionParametersForRequest(HttpURLConnection connection,
            Request<?> request) throws IOException, AuthFailureError {
        switch (request.getMethod()) {
            case Method.DEPRECATED_GET_OR_POST:
                // This is the deprecated way that needs to be handled for backwards compatibility.
                // If the request's post body is null, then the assumption is that the request is
                // GET.  Otherwise, it is assumed that the request is a POST.
                byte[] postBody = request.getPostBody();
                if (postBody != null) {
                    // Prepare output. There is no need to set Content-Length explicitly,
                    // since this is handled by HttpURLConnection using the size of the prepared
                    // output stream.
                    connection.setDoOutput(true);
                    connection.setRequestMethod("POST");
                    connection.addRequestProperty(HEADER_CONTENT_TYPE,
                            request.getPostBodyContentType());
                    DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                    out.write(postBody);
                    out.close();
                }
                break;
            case Method.GET:
                // Not necessary to set the request method because connection defaults to GET but
                // being explicit here.
                connection.setRequestMethod("GET");
                break;
            case Method.DELETE:
                connection.setRequestMethod("DELETE");
                break;
            case Method.POST:
                connection.setRequestMethod("POST");
                addBodyIfExists(connection, request);
                break;
            case Method.PUT:
                connection.setRequestMethod("PUT");
                addBodyIfExists(connection, request);
                break;
            default:
                throw new IllegalStateException("Unknown method type.");
        }
    }

    private static void addBodyIfExists(HttpURLConnection connection, Request<?> request)
            throws IOException, AuthFailureError {
        byte[] body = request.getBody();
        if (body != null) {
            connection.setDoOutput(true);
            connection.addRequestProperty(HEADER_CONTENT_TYPE, request.getBodyContentType());
            DataOutputStream out = new DataOutputStream(connection.getOutputStream());
            out.write(body);
            out.close();
        }
    }
}

从这个代码中可以看到,

 

         可以看到这里边他调用了getHeaders这个方法,会给你添加相应的头部,所以,也可以使用这个。

时间: 2024-12-23 04:03:47

Volley框架源码修改,添加头部验证Hreaders问题的相关文章

CI框架源码阅读笔记2 一切的入口 index.php

上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中,我们并不会逐行进行解释,而只解释核心的功能和实现. 1. 设置应用程序环境 define("ENVIRONMENT", "development"); 这里的development可以是任何你喜欢的环境名称(比如dev,再如test),相对应的,你要在下面的switch

如何对Spark 源码修改后在Eclipse中使用

问题描述 以前是在Eclipse新建项目,通过Maven导入的Spark依赖包,现在需要对Spark源码修改.从官网下载了SourceCode,修改后不知道怎么在Eclipse项目里使用,希望得到大神的指点! 解决方案 解决方案二:Eclipse下开发调试环境的配置该小节中使用的各项工具分别为:Windows7+EclipseJavaEE4.4.2+Scala2.10.4+Sbt0.13.8+Maven3.3.3,测试的Spark版本为1.4.0.1.配置IDE:选择菜单项Help->Insta

【自然框架】重新整理后的自然框架源码!

  整理后的自然框架源码,有九个项目,可以看下面的脑图,带"对号"的表示是一个独立的项目.后面的是主要内容.   欢迎下载http://www.naturefw.com/Down/kind38/List1.aspx ,但是请保留源码里的版权信息,以及dll里的版权信息. 自然框架源码采用 LGPL 2.1版本(GNU Lesser General Public License) 开源协议,http://www.naturefw.com/nature/license.aspx 可以先看看

PHP yii框架源码阅读(二) 整体执行流程分析

一 程序入口 <?php // change the following paths if necessary $yii=dirname(__FILE__).'/http://www.cnblogs.com/framework/yii.php'; $config=dirname(__FILE__).'/protected/config/main.php'; // remove the following line when in production mode // defined('YII_D

引入prototype文件夹下validation.js源码修改问题?

问题描述 引入prototype文件夹下validation.js源码修改问题? 最近修改一个bug,页面上如果出现一组复选框并且配置为必选时,必须全部学则,否则无法通过校验.看了代码发现是prototype文件夹下一个validation.js的文件来实现校验的.通过获取页面元素标签中的class属性进行判断. 但是问题就出现在这里,当有一组checkbox或者radio存在时,但他们仅对应一个业务意义就是说只需要点一个.但是由于这些标签是后台拼出来由于所以每个checkbox都会有class

eclipse中阅读开源源码包时,如何对源码包添加书签?

问题描述 eclipse中阅读开源源码包时,如何对源码包添加书签? eclipse中阅读源码包时,如何对源码包添加书签?或者有其他更好的阅读开源源码包的方法? 解决方案 添加书签是个什么意思?没明白...可以写注释作为标记.

基于ArcGIS的JLKEngine中间件平台可带框架源码购买并提供免费升级服务!

问题描述 基于ArcGIS的JLKEngine中间件平台底层类库结构简介1,系统总体上划分为如下几个层次:JLKEngine核心库:它是JLKEnigne的运行基础,定义了框架运行模型.框架扩展模式.并对ArcGISEngine中可用的操作进行了封装,提供了一组函数实现对空间数据的快速处理,以便于在基于ArcGISEngine的应用系统开发中应用以简化开发工作难度.GIS基础功能库:它是在ArcGISEngine基础上按地图制图.数据编辑.网络分析.三维分析等对数据处理划分的一组类库.在这组

openfire部署问题,本地源码修改,如何替换到测试环境

问题描述 openfire部署问题,本地源码修改,如何替换到测试环境 我在本地和测试环境都部署好了openfire的服务器,服务器启动成功,客户端也可以访问:如果本地openfire服务器的源码修改了.如何将本地修改后的openfire源码替换到测试环境呢? 普通的项目直接替换中间件的war就行,例如 tomcat weblogic等,但是jetty如何替换呢?

CI框架源码解读之利用Hook.php文件完成功能扩展的方法_php实例

本文实例讲述了CI框架源码解读之利用Hook.php文件完成功能扩展的方法.分享给大家供大家参考,具体如下: 看了hook.php的源码,就知道CI使用hook来进行扩展的原理了. hook的基本知识 http://codeigniter.org.cn/user_guide/general/hooks.html CI中hook的使用经历了一个:开启hook,定义hook,调用hook,执行hook的过程. 手册中已经告知了开启.定义.调用的方法.那么hook的实现原理是啥呢. <?php if