当前位置: 首页 > 知识库问答 >
问题:

Android:Volley HTTP补丁请求

籍星汉
2023-03-14

我刚刚开始从我现有的网络库移植到Android的Volley。到目前为止,我已经成功地实现了适用的Volleys ImageLoader。现在,我试图让我的第一个超文本传输协议调用和运行,但我发现这个错误。

注意:我有意以补丁请求开始,因为我将经常使用它们。另外,我的版本Volley也支持补丁:https://android.googlesource.com/platform/frameworks/volley//master/src/com/android/volley/Request。JAVAhttps://android.googlesource.com/platform/frameworks/volley//master/src/com/android/volley/toolbox/hurstack。JAVA

堆栈跟踪:

E/InputDialogFragment(27940): VolleyError: java.net.ProtocolException: Connection already established
D/Volley  (27940): [1] MarkerLog.finish: (67   ms) [ ] https://mobile.example.com/m/api/v1/user/ 0xb33a3c8d NORMAL 2
D/Volley  (27940): [1] MarkerLog.finish: (+0   ) [ 1] add-to-queue
D/Volley  (27940): [1] MarkerLog.finish: (+0   ) [544] cache-queue-take
D/Volley  (27940): [1] MarkerLog.finish: (+0   ) [544] cache-miss
D/Volley  (27940): [1] MarkerLog.finish: (+0   ) [545] network-queue-take
D/Volley  (27940): [1] MarkerLog.finish: (+14  ) [545] post-error
D/Volley  (27940): [1] MarkerLog.finish: (+53  ) [ 1] done

补丁请求

    HashMap<String, Object> values = new HashMap<String, Object>();
    values.put(mParam, val);
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.PATCH, APIConstants.URL_USER, new JSONObject(values),
        new Response.Listener<JSONObject>(){
            @Override
            public void onResponse(JSONObject response){
               // Blah do stuff here 
                mProgressDialog.dismiss();
            }
        },
        new Response.ErrorListener(){
            @Override
            public void onErrorResponse(VolleyError error){
                Log.e(TAG, "VolleyError: " + error.getMessage());
            }
        }){
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                HashMap<String, String> headers = new HashMap<String, String>();
                VolleySingleton.getInstance().addCookie(headers);
                return headers;
            }
    };
    VolleySingleton.getInstance().getRequestQueue().add(request);

是的,我计划最终为StringRequest、JsonObjectRequest等构建类。。。但目前我只想让它运行起来。

另外,如果您想了解addCookie,现在我更喜欢将我的cookie保存在preferences中,因为我对CookieManager不太熟悉。

单打截击

public class VolleySingleton {
    private static final String COOKIE_KEY = "Cookie";
    private static VolleySingleton mInstance = null;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private SharedPreferences mPreferences;
    private VolleySingleton(){
        mRequestQueue = Volley.newRequestQueue(MyApplication.getAppContext());
        mImageLoader = new ImageLoader(this.mRequestQueue, new ImageLoader.ImageCache() {
            private final LruCache<String, Bitmap> mCache = new LruCache<String, Bitmap>(10);
            public void putBitmap(String url, Bitmap bitmap) {
                mCache.put(url, bitmap);
            }
            public Bitmap getBitmap(String url) {
                return mCache.get(url);
            }
        });
        mPreferences = MyApplication.getAppContext().getSharedPreferences(PrefConstants.PREFERENCES, 0);
    }

    public static VolleySingleton getInstance(){
        if(mInstance == null){
            mInstance = new VolleySingleton();
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue(){
        return this.mRequestQueue;
    }

    public ImageLoader getImageLoader(){
        return this.mImageLoader;
    }

    public final void addCookie(Map<String, String> headers) {
        String cookie = mPreferences.getString(PrefConstants.PREF_COOKIE, null);
        if(cookie != null){
            headers.put(COOKIE_KEY, cookie);
        }
    }
}

共有3个答案

邢同
2023-03-14

我知道这个问题由来已久,但提供解决方案可以帮助尚未遇到同样挑战的人

JSONObject param = new JSONObject();
    try {
        param.put(KEY 1, VALUE 1);
        param.put(KEY 2, VALUE 2);

    } catch (JSONException e) {
        e.printStackTrace();
    }

        //ID represents the id for the record to update
    JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.PATCH, YOUR URL+ "?ID=" + ID, param,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                 //call handler to display response (optional)

                }
            }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            //call handler to display response (optional)

        }

    }) {

        //            Passing header
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/json; charset=utf-8");
            headers.put("x-api-key", "YOUR API KEY");
            return headers;
        }

        @Override
        protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {

           //use this to check positive response code returned else remove this override part

            return super.parseNetworkResponse(response);
        }
    };
    //and then you pass json data to volley
    VolleySingleton.getInstance(getActivity()).addToRequestQueue(jsonObjReq);
阚乐湛
2023-03-14

我也遇到了这个问题,我的解决方案是放弃底层内置的Apache HTTP组件,使用Square中的OkHttp库,使用这个HttpStack实现,用于使用OkHttp作为传输的Volley。效果很好。

管炳
2023-03-14

问题:

Volleys HurlStack(HttpUrlConnection)确实有补丁的支持代码。但是,每当您尝试发出补丁请求时,它似乎仍然会抛出“我的标题”和“堆栈跟踪”中发布的异常。

黑客解决方案

1) 强制截击使用HttpClientStack。

下面是我的截击单例构造函数的更新版本。这“可行”,但显然浪费了Hull实现,如果(Build.VERSION.SDK_INT

private VolleySingleton(){
    mPreferences = MyApplication.getAppContext().getSharedPreferences(PrefConstants.PREFERENCES, 0);

    String userAgent = "volley/0";
    try {
        String packageName = MyApplication.getAppContext().getPackageName();
        PackageInfo info = MyApplication.getAppContext().getPackageManager().getPackageInfo(packageName, 0);
        userAgent = packageName + "/" + info.versionCode;
    } catch (NameNotFoundException e) {}

    HttpStack httpStack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
    mRequestQueue = Volley.newRequestQueue(MyApplication.getAppContext(), httpStack);
    mImageLoader = new ImageLoader(this.mRequestQueue, new ImageLoader.ImageCache() {
        private final LruCache<String, Bitmap> mCache = new LruCache<String, Bitmap>(10);
        public void putBitmap(String url, Bitmap bitmap) {
            mCache.put(url, bitmap);
        }
        public Bitmap getBitmap(String url) {
            return mCache.get(url);
        }
    });
}

2)继续使用上面的VolleySingleton仅用于补丁;将其重命名为VolleySingletonPatch(),然后当然为所有其他非补丁调用创建默认VolleySingleton()。(

3) 解决HurlStack中抛出的异常,尽管Volley已经实现了补丁。这将是最好的,但我宁愿避免直接修补凌空或者不必要地扩展我自己的httpstack。

我没有回答这个问题,因为我非常感谢任何见解,当然还有比我在这里提出的更好的选择。

 类似资料:
  • Git 中的一些命令是以引入的变更即提交这样的概念为中心的,这样一系列的提交,就是一系列的补丁。 这些命令以这样的方式来管理你的分支。 git cherry-pick git cherry-pick 命令用来获得在单个提交中引入的变更,然后尝试将作为一个新的提交引入到你当前分支上。 从一个分支单独一个或者两个提交而不是合并整个分支的所有变更是非常有用的。 在 变基与拣选工作流 一节中描述和演示了

  • 问题内容: 我正在使用djang-tastypie作为后端和AngularJs作为前端的API。我正在使用angularjs $ http从CRUD发送请求。GET,POST,PUT一切都很好,但是当我尝试发送PATCH请求时,出现错误,未定义PATCH方法。我已经在angular中创建了一个api调用工厂,但是PATCH请求在那里不起作用。 这是我的HTML代码 当我在控制台中使用此代码发送路径

  • 有没有办法在spring boot中验证补丁请求主体? 如果任何用户发送请求时,“op”(字段)为“xx”,而“path”(字段)为“se”。有没有办法在不更改合同的情况下验证它并抛出400(错误的请求)?

  • 向app store发布新的app版本可能需要一些时间。Tabris.js允许直接向你的用户发布热更新,而无需等待app store更新。 为了符合Apple App Store的规则,修补程序必须“[…] not change the primary purpose of the app by providing features or functionality that are incons

  • 问题内容: 我对AngularJs完全陌生。我正在尝试使用Angularjs向Django Deliciouspie API发送PATCH请求。我的代码是 但是,当我尝试使用此代码发送请求时,出现了一个错误消息,即http.patch不是函数。告诉我如何配置ng- app和服务以使用AngularJs发送PATCH请求。我读过PATCH请求在$ resource中可用,所以我也对$ resourc

  • 在我的spring-boot服务中,我使用https://github.com/java-json-tools/json-patch用于处理PATCH请求。 一切似乎都很好,除了一种避免修改不可变字段的方法,如对象ID、creation_time等。我在Github上发现了一个类似的问题https://github.com/java-json-tools/json-patch/issues/21我