zoukankan      html  css  js  c++  java
  • android Volley 上传文件上传图片

    Volley不解释了吧, android 官方的一个网络请求库.


    源码的地址在:

    git@github.com:com314159/VolleyMultiPartRequest.git

    上面的是ssh

    以下的是http地址

    https://github.com/com314159/VolleyMultiPartRequest


    是依据

    https://github.com/smanikandan14/Volley-demo

    这位大神改动而来的, 可是那位大神的代码有bug, 上传文件不成功.


    注: 我的demo里面还集成了okhttp, 不须要的同学不用理这个类就可以


    实现方法:

    1.加入三个jar包,

    httpcore-4.3.2.jar

    httpclient-4.3.5.jar

    httpmime-4.3.5.jar


    2.实现MultiPartStack

    package com.example.volleytest;
    
    
    import java.io.File;
    import java.io.IOException;
    import java.util.Map;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    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.HttpPatch;
    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.entity.ContentType;
    import org.apache.http.entity.mime.HttpMultipartMode;
    import org.apache.http.entity.mime.MultipartEntityBuilder;
    import org.apache.http.entity.mime.content.FileBody;
    import org.apache.http.entity.mime.content.StringBody;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.params.HttpConnectionParams;
    import org.apache.http.params.HttpParams;
    import org.apache.http.protocol.HTTP;
    
    import com.android.volley.AuthFailureError;
    import com.android.volley.Request;
    import com.android.volley.Request.Method;
    import com.android.volley.toolbox.HurlStack;
    
    /**
     * @author ZhiCheng Guo
     * @version 2014年10月7日 上午11:00:52 这个Stack用于上传文件, 假设没有这个Stack, 则上传文件不成功
     */
    public class MultiPartStack extends HurlStack {
    	@SuppressWarnings("unused")
    	private static final String TAG = MultiPartStack.class.getSimpleName();
        private final static String HEADER_CONTENT_TYPE = "Content-Type";
    	
    	
    	
    	
    	@Override
    	public HttpResponse performRequest(Request<?

    > request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError { if(!(request instanceof MultiPartRequest)) { return super.performRequest(request, additionalHeaders); } else { return performMultiPartRequest(request, additionalHeaders); } } private static void addHeaders(HttpUriRequest httpRequest, Map<String, String> headers) { for (String key : headers.keySet()) { httpRequest.setHeader(key, headers.get(key)); } } public HttpResponse performMultiPartRequest(Request<?

    > request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError { HttpUriRequest httpRequest = createMultiPartRequest(request, additionalHeaders); addHeaders(httpRequest, additionalHeaders); addHeaders(httpRequest, request.getHeaders()); 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); /* Make a thread safe connection manager for the client */ HttpClient httpClient = new DefaultHttpClient(httpParams); return httpClient.execute(httpRequest); } static HttpUriRequest createMultiPartRequest(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.getBody(); if (postBody != null) { HttpPost postRequest = new HttpPost(request.getUrl()); if(request.getBodyContentType() != null) postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType()); HttpEntity entity; entity = new ByteArrayEntity(postBody); postRequest.setEntity(entity); return postRequest; } else { return new HttpGet(request.getUrl()); } } case Method.GET: return new HttpGet(request.getUrl()); case Method.DELETE: return new HttpDelete(request.getUrl()); case Method.POST: { HttpPost postRequest = new HttpPost(request.getUrl()); postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType()); setMultiPartBody(postRequest,request); return postRequest; } case Method.PUT: { HttpPut putRequest = new HttpPut(request.getUrl()); if(request.getBodyContentType() != null) putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType()); setMultiPartBody(putRequest,request); return putRequest; } // Added in source code of Volley libray. case Method.PATCH: { HttpPatch patchRequest = new HttpPatch(request.getUrl()); if(request.getBodyContentType() != null) patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType()); return patchRequest; } default: throw new IllegalStateException("Unknown request method."); } } /** * If Request is MultiPartRequest type, then set MultipartEntity in the * httpRequest object. * * @param httpRequest * @param request * @throws AuthFailureError */ private static void setMultiPartBody(HttpEntityEnclosingRequestBase httpRequest, Request<?> request) throws AuthFailureError { // Return if Request is not MultiPartRequest if (!(request instanceof MultiPartRequest)) { return; } // MultipartEntity multipartEntity = new // MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); /* example for setting a HttpMultipartMode */ builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); // Iterate the fileUploads Map<String, File> fileUpload = ((MultiPartRequest) request).getFileUploads(); for (Map.Entry<String, File> entry : fileUpload.entrySet()) { builder.addPart(((String) entry.getKey()), new FileBody((File) entry.getValue())); } ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8); // Iterate the stringUploads Map<String, String> stringUpload = ((MultiPartRequest) request).getStringUploads(); for (Map.Entry<String, String> entry : stringUpload.entrySet()) { try { builder.addPart(((String) entry.getKey()), new StringBody((String) entry.getValue(), contentType)); } catch (Exception e) { e.printStackTrace(); } } httpRequest.setEntity(builder.build()); } }



    3. 实现MultiPartRequest, 这个接口是为了方便扩展

    package com.example.volleytest;
    
    import java.io.File;
    import java.util.Map;
    
    /**
     * @author ZhiCheng Guo
     * @version 2014年10月7日 上午11:04:36
     */
    public interface MultiPartRequest {
    
        public void addFileUpload(String param,File file); 
        
        public void addStringUpload(String param,String content); 
        
        public Map<String,File> getFileUploads();
        
        public Map<String,String> getStringUploads(); 
    }


    /**
     * Copyright 2013 Mani Selvaraj
     *
     * 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.example.volleytest;
    
    import java.io.File;
    import java.io.UnsupportedEncodingException;
    import java.util.HashMap;
    import java.util.Map;
    
    import com.android.volley.NetworkResponse;
    import com.android.volley.Request;
    import com.android.volley.Response;
    import com.android.volley.Response.ErrorListener;
    import com.android.volley.Response.Listener;
    import com.android.volley.toolbox.HttpHeaderParser;
    
    /**
     * MultipartRequest - To handle the large file uploads.
     * Extended from JSONRequest. You might want to change to StringRequest based on your response type.
     * @author Mani Selvaraj
     *
     */
    public class MultiPartStringRequest extends Request<String> implements MultiPartRequest{
    
    	private final Listener<String> mListener;
    	/* To hold the parameter name and the File to upload */
    	private Map<String,File> fileUploads = new HashMap<String,File>();
    	
    	/* To hold the parameter name and the string content to upload */
    	private Map<String,String> stringUploads = new HashMap<String,String>();
    	
        /**
         * Creates a new request with the given method.
         *
         * @param method the request {@link Method} to use
         * @param url URL to fetch the string at
         * @param listener Listener to receive the String response
         * @param errorListener Error listener, or null to ignore errors
         */
        public MultiPartStringRequest(int method, String url, Listener<String> listener,
                ErrorListener errorListener) {
            super(method, url, errorListener);
            mListener = listener;
        }
    
    
    
        public void addFileUpload(String param,File file) {
        	fileUploads.put(param,file);
        }
        
        public void addStringUpload(String param,String content) {
        	stringUploads.put(param,content);
        }
        
        /**
         * 要上传的文件
         */
        public Map<String,File> getFileUploads() {
        	return fileUploads;
        }
        
        /**
         * 要上传的參数
         */
        public Map<String,String> getStringUploads() {
        	return stringUploads;
        }
        
    
        @Override
        protected Response<String> parseNetworkResponse(NetworkResponse response) {
            String parsed;
            try {
                parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            } catch (UnsupportedEncodingException e) {
                parsed = new String(response.data);
            }
            return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
        }
    
    	@Override
    	protected void deliverResponse(String response) {
    		if(mListener != null) {
    			mListener.onResponse(response);
    		}
    	}
    	
    	/**
    	 * 空表示不上传
    	 */
        public String getBodyContentType() {
            return null;
        }
    }

    3.用法和volley原生的request的用法是一样的, 仅仅是要使用新的Stack, 如以下的是put的方法的用法. 假设是post, 就改动成post方法就能够了

            RequestQueue mSingleQueue = Volley.newRequestQueue(this, new MultiPartStack());
    
    
        MultiPartStringRequest multiPartRequest = new MultiPartStringRequest(
                Request.Method.PUT, url, responseListener, errorListener) {
    
            @Override
            public Map<String, File> getFileUploads() {
                return files;
            }
    
            @Override
            public Map<String, String> getStringUploads() {
                return params;
            }
    
        };
    
        mSingeQueue.add(multiPartRequest)



  • 相关阅读:
    synchronized一个(二)
    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
    java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout
    NTFS簇大小对硬盘性能的影响测试
    Win10 开机自动打开上次未关闭程序怎么办
    Win10快速访问怎么关闭?
    激活windows 10 LTSC 2019(无需工具)
    WPS文字双行合一
    插入百度地图代码后,页面文字不能被选中的解决方案
    WPS文字批量选中整行(以第?章为例)
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6743164.html
Copyright © 2011-2022 走看看