應項目要求修改網絡問題,為了讓項目更加健壯,使用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 這種通路網絡的方式,
import org.apache.http.header;
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.inputstream;
import java.net.httpurlconnection;
import java.net.url;
import java.util.hashmap;
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 sslsocketfactory ssl factory to use for https connections
public hurlstack(urlrewriter urlrewriter, sslsocketfactory sslsocketfactory) {
murlrewriter = urlrewriter;
msslsocketfactory = sslsocketfactory;
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);
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;
/* package */ static void setconnectionparametersforrequest(httpurlconnection connection,
request<?> request) throws ioexception, authfailureerror {
case method.deprecated_get_or_post:
// 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;
// not necessary to set the request method because connection defaults to get but
// being explicit here.
connection.setrequestmethod("get");
connection.setrequestmethod("delete");
case method.post:
connection.setrequestmethod("post");
addbodyifexists(connection, request);
case method.put:
connection.setrequestmethod("put");
throw new illegalstateexception("unknown method type.");
private static void addbodyifexists(httpurlconnection connection, request<?> request)
connection.setdooutput(true);
connection.addrequestproperty(header_content_type, request.getbodycontenttype());
dataoutputstream out = new dataoutputstream(connection.getoutputstream());
out.write(body);
out.close();
從這個代碼中可以看到,

可以看到這裡邊他調用了getheaders這個方法,會給你添加相應的頭部,是以,也可以使用這個。