【问题标题】:How to set custom header in Volley Request如何在 Volley Request 中设置自定义标头
【发布时间】:2013-06-11 16:45:15
【问题描述】:

如何为 Volley 请求设置自定义标头?目前,有一种方法可以为 POST 请求设置正文内容。我有一个简单的 GET 请求,但我需要同时传递自定义标头。我看不到 JsonRequest 类如何支持它。有可能吗?

【问题讨论】:

  • 请更改接受的答案,当前接受的答案不正确。

标签: android android-volley


【解决方案1】:

getParams() 接受的答案是设置 POST 正文数据,但标题中的问题询问如何设置 HTTP 标头,如 User-Agent。正如 CommonsWare 所说,您覆盖 getHeaders()。下面是一些示例代码,将 User-Agent 设置为“Nintendo Gameboy”,Accept-Language 设置为“fr”:

public void requestWithSomeHttpHeaders() {
    RequestQueue queue = Volley.newRequestQueue(this);
    String url = "http://www.somewebsite.com";
    StringRequest getRequest = new StringRequest(Request.Method.GET, url, 
        new Response.Listener<String>() 
        {
            @Override
            public void onResponse(String response) {
                // response
                Log.d("Response", response);
            }
        }, 
        new Response.ErrorListener() 
        {
            @Override
            public void onErrorResponse(VolleyError error) {
                // TODO Auto-generated method stub
                Log.d("ERROR","error => "+error.toString());
            }
        }
    ) {     
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError { 
                Map<String, String>  params = new HashMap<String, String>();  
                params.put("User-Agent", "Nintendo Gameboy");  
                params.put("Accept-Language", "fr");

                return params;  
        }
    };
    queue.add(getRequest);

}

【讨论】:

  • 这个答案也适用于 JSONObjectRequest 吗? JSONObjectRequest postRequest = new JSONObjectRequest ......因为我正在这样做并且我的 getHeaders() 没有被调用......???我了解您正在创建一个匿名类并覆盖这些方法。我这样做只是 w/ JSONObjectRequest 而不是 StringRequest 并且我的 getHeaders() 没有被调用。
  • 我们也可以在 getHeaders() 方法中添加“Cookie”吗?它也适用于发布请求吗?
  • 我会将其余的 POST 数据发送到哪里?
【解决方案2】:

您似乎覆盖了public Map&lt;String, String&gt; getHeaders()defined in Request,以返回所需的 HTTP 标头。

【讨论】:

【解决方案3】:

如果您需要的是发布数据而不是在 url 中添加信息。

public Request post(String url, String username, String password, 
      Listener listener, ErrorListener errorListener) {
  JSONObject params = new JSONObject();
  params.put("user", username);
  params.put("pass", password);
  Request req = new Request(
     Method.POST,
     url,
     params.toString(),
     listener,
     errorListener
  );

  return req;
}

如果您想要编辑请求中的标头,这就是您想要做的:

// could be any class that implements Map
Map<String, String> mHeaders = new ArrayMap<String, String>();
mHeaders.put("user", USER);
mHeaders.put("pass", PASSWORD);
Request req = new Request(url, postBody, listener, errorListener) {
  public Map<String, String> getHeaders() {
    return mHeaders;
  }
}

【讨论】:

  • 我投了反对票,因为这根本不是问题所在。这是用于设置 POST 内容,而不是用于设置自定义 HTTP 标头,如 User-Agent。 ZH。 Atanasov 和 CommonsWare 的 getHeaders 答案是正确的。
  • 我否决了这个答案,因为这不是用户所要求的。
  • 这是为了添加内容参数而不是标题,抱歉也被否决了。这真的不应该是公认的答案
  • 请你看看我的问题?它与此类似,但我无法正确处理stackoverflow.com/a/37948318
【解决方案4】:

您可以看到this 解决方案。它显示了如何获取/设置 cookie,但 cookie 只是请求/响应中的标头之一。您必须覆盖 Volley 的 *Request 类之一并在 getHeaders() 中设置所需的标头


这里是链接源:

public class StringRequest extends com.android.volley.toolbox.StringRequest {

private final Map<String, String> _params;

/**
 * @param method
 * @param url
 * @param params
 *            A {@link HashMap} to post with the request. Null is allowed
 *            and indicates no parameters will be posted along with request.
 * @param listener
 * @param errorListener
 */
public StringRequest(int method, String url, Map<String, String> params, Listener<String> listener,
        ErrorListener errorListener) {
    super(method, url, listener, errorListener);

    _params = params;
}

@Override
protected Map<String, String> getParams() {
    return _params;
}

/* (non-Javadoc)
 * @see com.android.volley.toolbox.StringRequest#parseNetworkResponse(com.android.volley.NetworkResponse)
 */
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
    // since we don't know which of the two underlying network vehicles
    // will Volley use, we have to handle and store session cookies manually
    MyApp.get().checkSessionCookie(response.headers);

    return super.parseNetworkResponse(response);
}

/* (non-Javadoc)
 * @see com.android.volley.Request#getHeaders()
 */
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String, String> headers = super.getHeaders();

    if (headers == null
            || headers.equals(Collections.emptyMap())) {
        headers = new HashMap<String, String>();
    }

    MyApp.get().addSessionCookie(headers);

    return headers;
}

}

还有 MyApp 类:

public class MyApp extends Application {
    private static final String SET_COOKIE_KEY = "Set-Cookie";
    private static final String COOKIE_KEY = "Cookie";
    private static final String SESSION_COOKIE = "sessionid";

    private static MyApp _instance;
    private RequestQueue _requestQueue;
    private SharedPreferences _preferences;

    public static MyApp get() {
        return _instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        _instance = this;
            _preferences = PreferenceManager.getDefaultSharedPreferences(this);
        _requestQueue = Volley.newRequestQueue(this);
    }

    public RequestQueue getRequestQueue() {
        return _requestQueue;
    }


    /**
     * Checks the response headers for session cookie and saves it
     * if it finds it.
     * @param headers Response Headers.
     */
    public final void checkSessionCookie(Map<String, String> headers) {
        if (headers.containsKey(SET_COOKIE_KEY)
                && headers.get(SET_COOKIE_KEY).startsWith(SESSION_COOKIE)) {
                String cookie = headers.get(SET_COOKIE_KEY);
                if (cookie.length() > 0) {
                    String[] splitCookie = cookie.split(";");
                    String[] splitSessionId = splitCookie[0].split("=");
                    cookie = splitSessionId[1];
                    Editor prefEditor = _preferences.edit();
                    prefEditor.putString(SESSION_COOKIE, cookie);
                    prefEditor.commit();
                }
            }
    }

    /**
     * Adds session cookie to headers if exists.
     * @param headers
     */
    public final void addSessionCookie(Map<String, String> headers) {
        String sessionId = _preferences.getString(SESSION_COOKIE, "");
        if (sessionId.length() > 0) {
            StringBuilder builder = new StringBuilder();
            builder.append(SESSION_COOKIE);
            builder.append("=");
            builder.append(sessionId);
            if (headers.containsKey(COOKIE_KEY)) {
                builder.append("; ");
                builder.append(headers.get(COOKIE_KEY));
            }
            headers.put(COOKIE_KEY, builder.toString());
        }
    }

}

【讨论】:

    【解决方案5】:

    在 Kotlin 中,

    您必须重写 getHeaders() 方法,例如:

    val volleyEnrollRequest = object : JsonObjectRequest(GET_POST_PARAM, TARGET_URL, PAYLOAD_BODY_IF_YOU_WISH,
                Response.Listener {
                    // Success Part  
                },
    
                Response.ErrorListener {
                    // Failure Part
                }
            ) {
                // Providing Request Headers
    
                override fun getHeaders(): Map<String, String> {
                   // Create HashMap of your Headers as the example provided below
    
                    val headers = HashMap<String, String>()
                    headers["Content-Type"] = "application/json"
                    headers["app_id"] = APP_ID
                    headers["app_key"] = API_KEY
    
                    return headers
                }
            }
    

    【讨论】:

    • 这是我能在 Kotlin 中找到的用于覆盖标头的唯一资源。谢谢!
    • @MathewSonke 我觉得你是兄弟。顺便说一句,请尝试在 Android 中进行网络改造。
    【解决方案6】:

    也在寻找解决这个问题的方法。 在这里看到一些东西:http://developer.android.com/training/volley/request.html

    直接使用 ImageRequest 而不是 ImageLoader 是个好主意吗?似乎 ImageLoader 无论如何都在内部使用它。除了 ImageLoader 的缓存支持之外,它是否遗漏了什么重要的东西?

    ImageView mImageView;
    String url = "http://i.imgur.com/7spzG.png";
    mImageView = (ImageView) findViewById(R.id.myImage);
    ...
    
    // Retrieves an image specified by the URL, displays it in the UI.
    mRequestQueue = Volley.newRequestQueue(context);;
    ImageRequest request = new ImageRequest(url,
      new Response.Listener() {
          @Override
          public void onResponse(Bitmap bitmap) {
              mImageView.setImageBitmap(bitmap);
          }
      }, 0, 0, null,
      new Response.ErrorListener() {
          public void onErrorResponse(VolleyError error) {
              mImageView.setImageResource(R.drawable.image_load_error);
          }
      })   {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> params = new Map<String, String>();
            params.put("User-Agent", "one");
            params.put("header22", "two");
    
            return params;
        };
    mRequestQueue.add(request);
    

    【讨论】:

    • 如果您能指出为什么您认为问题是错误的或所提出的解决方案有问题,而不是简单地给它一个“-1”,我们将非常感激和更有帮助。
    • 地图是抽象的。应该是HashMap
    【解决方案7】:

    试试这个

    {
        @Override
           public Map<String, String> getHeaders() throws AuthFailureError {
               String bearer = "Bearer ".concat(token);
                Map<String, String> headersSys = super.getHeaders();
                Map<String, String> headers = new HashMap<String, String>();
                headersSys.remove("Authorization");
                headers.put("Authorization", bearer);
                headers.putAll(headersSys);
                return headers;
           }
    };
    

    【讨论】:

      【解决方案8】:

      您可以创建一个扩展 StringRequest 的自定义 Request 类并覆盖其中的 getHeaders() 方法,如下所示:

      public class CustomVolleyRequest extends StringRequest {
      
          public CustomVolleyRequest(int method, String url,
                                 Response.Listener<String> listener,
                                 Response.ErrorListener errorListener) {
              super(method, url, listener, errorListener);
          }
      
          @Override
          public Map<String, String> getHeaders() throws AuthFailureError {
              Map<String, String> headers = new HashMap<>();
              headers.put("key1","value1");
              headers.put("key2","value2");
              return headers;
          }
      }
      

      【讨论】:

        【解决方案9】:
        public class CustomJsonObjectRequest  extends JsonObjectRequest
        {
            public CustomJsonObjectRequest(int method, String url, JSONObject jsonRequest,Response.Listener listener, Response.ErrorListener errorListener)
            {
                super(method, url, jsonRequest, listener, errorListener);
            }
        
        
        @Override
        public Map getHeaders() throws AuthFailureError {
            Map headers = new HashMap();
            headers.put("AppId", "xyz");
        
            return headers;
        }
        
        }
        

        【讨论】:

          【解决方案10】:

          作为补充,我想分享一些关于Content-Type 的发现: 在

          之上
          @Override
          public Map<String, String> getHeaders() throws AuthFailureError {
          Map<String, String> params = new HashMap<String, String>();
          .
          .
          .
          return params;
          }
          

          我必须补充:

          @Override
          public String getBodyContentType() {
          return /*(for exmaple)*/ "application/json";
          }
          

          不要问我为什么,我只是认为它可能会帮助一些无法正确设置 Content-Type 的其他人。

          【讨论】:

            【解决方案11】:

            这里是来自 github 示例的设置标题:

            StringRequest myReq = new StringRequest(Method.POST,
                                   "http://ave.bolyartech.com/params.php",
                                    createMyReqSuccessListener(),
                                    createMyReqErrorListener()) {
            
             protected Map<String, String> getParams() throws 
                     com.android.volley.AuthFailureError {
                                    Map<String, String> params = new HashMap<String, String>();
                                    params.put("param1", num1);
                                    params.put("param2", num2);
                                    return params;
                                };
                            };
                            queue.add(myReq);
            

            【讨论】:

              【解决方案12】:

              试试这个

               public void VolleyPostReqWithResponseListenerwithHeaders(String URL,final Map<String, String> params,final Map<String, String> headers,Response.Listener<String> responseListener) {
              
              
                  String url = URL;
              
                  Log.i("url:", ":" + url);
                  StringRequest mStringRequest = new StringRequest(Request.Method.POST,
                          url, responseListener, new Response.ErrorListener() {
                      @Override
                      public void onErrorResponse(VolleyError error) {
                          // error
              
              
                          //Log.d("Error.Response", error.getLocalizedMessage());
                      }
                  }){
                      @Override
                      protected Map<String, String> getParams() {
                          return params;
                      }
              
                      @Override
                      public Map<String, String> getHeaders() throws AuthFailureError {
                          return headers;
                      }
                  };
              
              
              
                  mStringRequest.setRetryPolicy(new DefaultRetryPolicy(
                          60000,
                          DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                          DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
              
                  mStringRequest.setShouldCache(true);
              
              
              
                  //  dialog.show();
                  SingletonRequestQueue.getInstance(context).addToRequestQueue(mStringRequest);
              }
              

              【讨论】:

              • @Override public Map getHeaders() throws AuthFailureError { return headers; } };
              • 标题在哪里??
              • 在签名时,您可以在使用 Map headers 调用时设置它
              【解决方案13】:

              这是我的代码,别忘了 = object: if don't put don't works

              val queue = Volley.newRequestQueue(this)
                      val url = "http://35.237.133.137:8080/lamarrullaWS/rest/lamarrullaAPI"
                      // Request a string response from the provided URL.
                      val jsonObjectRequest = object: JsonObjectRequest(Request.Method.GET, url, null,
                              Response.Listener { response ->
                                  txtPrueba.text = "Response: %s".format(response.toString())
                              },
                              Response.ErrorListener { txtPrueba.text = "That didn't work!" }
                      )
                      {
                          @Throws(AuthFailureError::class)
                          override fun getHeaders(): Map<String, String> {
                              val headers = HashMap<String, String>()
                              headers.put("Content-Type", "application/json")
                              return headers
                          }
                      }
                      queue.add(jsonObjectRequest)
              

              【讨论】:

                猜你喜欢
                • 2016-03-20
                • 1970-01-01
                • 2016-06-21
                • 2012-01-18
                • 2016-04-02
                • 1970-01-01
                • 1970-01-01
                • 2016-12-28
                • 2017-01-03
                相关资源
                最近更新 更多