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

新api中不推荐使用HttpConnectionParams上载Android多部分图像

涂飞航
2023-03-14

我正在使用这个代码。

public class MultiPartRequester {
	private Map<String, String> map;
	private AsyncTaskCompleteListener mAsynclistener;
	private int serviceCode;
	private HttpClient httpclient;
	private Activity activity;
	private AsyncHttpRequest request;
	private static final String TAG = "MultiPartRequester";

	public MultiPartRequester(Activity activity, Map<String, String> map,
		int serviceCode, AsyncTaskCompleteListener asyncTaskCompleteListener) {
		this.map = map;
		this.serviceCode = serviceCode;
		this.activity = activity;
	}

	class AsyncHttpRequest extends AsyncTask<String, Void, String> {
		@Override
		protected String doInBackground(String... urls) {
			map.remove("url");
			try {
				HttpPost httppost = new HttpPost(urls[0]);
				httpclient = new DefaultHttpClient();
				HttpConnectionParams.setConnectionTimeout(
						httpclient.getParams(), 600000);
				MultipartEntityBuilder builder = MultipartEntityBuilder
						.create();
				for (String key : map.keySet()) {
					if (key.equalsIgnoreCase(AndyConstants.Params.PICTURE)) {
						File f = new File(map.get(key));
						builder.addBinaryBody(key, f,
								ContentType.MULTIPART_FORM_DATA, f.getName());
					} else {
						builder.addTextBody(key, map.get(key), ContentType
								.create("text/plain", MIME.UTF8_CHARSET));
					}
					AppLog.Log(TAG, key + "---->" + map.get(key));
				}
				httppost.setEntity(builder.build());
				ActivityManager manager = (ActivityManager) activity
						.getSystemService(Context.ACTIVITY_SERVICE);
				if (manager.getMemoryClass() < 25) {
					System.gc();
				}
				HttpResponse response = httpclient.execute(httppost);
				String responseBody = EntityUtils.toString(
						response.getEntity(), "UTF-8");
				reurn responseBody;
			} catch (Exception e) {
				e.printStackTrace();
			} catch (OutOfMemoryError oume) {
				System.gc();	
			} finally {
				if (httpclient != null)
					httpclient.getConnectionManager().shutdown();
			}
			return null;
		}

		@Override
		protected void onPostExecute(String response) {
			if (mAsynclistener != null) {
				mAsynclistener.onTaskCompleted(response, serviceCode);
			}
		}
	}
	public void cancelTask() {
		request.cancel(true);
		AppLog.Log(TAG, "task is canelled");
	}
}

共有1个答案

阎鸿煊
2023-03-14

这是FileUploadMultipartRequest类:

/**
 * Multipart request for sending files over http
 * also can return generic type of response data
 * @param <T> the type of data for http responses
 */
public class FileUploadMultipartRequest<T> extends BaseRequest<T>
{
    private static final MediaType JSON = MediaType.parse("application/json");
    private File[] files;
    private String jsonString;
    private RequestBody requestBody;

    public FileUploadMultipartRequest(String url, Map<String, String> headers, String jsonString, OnEmptyResponseListener listener, ErrorTypeListener errorListener, File... files)
    {
        super(Method.POST, url, headers, listener, new ErrorListenerImpl(errorListener));
        this.jsonString = jsonString;
        this.files = files;
    }

    public FileUploadMultipartRequest(String url, Map<String, String> headers, String jsonString, Type responseType, Response.Listener listener, ErrorTypeListener errorListener, File... files)
    {
        super(Method.POST, url, headers, responseType, listener, new ErrorListenerImpl(errorListener));
        this.jsonString = jsonString;
        this.files = files;
    }

    @Override
    public String getBodyContentType()
    {
        return buildMultipartEntity().contentType().toString();
    }

    @Override
    public byte[] getBody() throws AuthFailureError
    {
        Buffer buffer = new Buffer();
        try
        {
            buildMultipartEntity().writeTo(buffer);
        } catch (IOException e)
        {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return buffer.readByteArray();
    }

    private RequestBody buildMultipartEntity()
    {

        if (requestBody == null)
        {
            MultipartBuilder multipartBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);

            multipartBuilder.addPart(
                    Headers.of("Content-Disposition", "form-data; name=json-part"),
                    RequestBody.create(JSON, jsonString));

            for (File file : files)
            {
                String contentType = URLConnection.guessContentTypeFromName(file.getName());
                multipartBuilder.addFormDataPart("files-part", file.getName(),
                        RequestBody.create(MediaType.parse(contentType), file));
            }

            requestBody = multipartBuilder.build();
        }
        return requestBody;
    }

}

这是BaseRequest类:

/**
 * this a abstract request class for handling http http responses
 * note : all volley request should extend this class for http request
 *
 * @param <T> the type of data for http responses
 */
public abstract class BaseRequest<T> extends Request<T>
{
    private final Map<String, String> headers;

    /**
     * the type response that {@link com.android.volley.Response.Listener} should return
     */
    private Type responseType;

    /**
     * generic listener for successful http request
     */
    private Response.Listener<T> listener;

    /**
     * constructor for request that returns data type {@link T}
     *
     * @param method        http verb e.g. POST, GET & etc
     * @param url           request URL
     * @param headers       http headers
     * @param responseType  type of data that response should return
     * @param listener      event for successful request
     * @param errorListener event for failed request
     */
    public BaseRequest(int method, String url, Map<String, String> headers, Type responseType, Response.Listener listener, ErrorListenerImpl errorListener)
    {
        super(method, url, errorListener);
        this.headers = headers;
        this.responseType = responseType;
        //noinspection unchecked
        this.listener = listener;
    }

    /**
     * constructor for requests with no returning data
     *  @param method                  http verb e.g. POST, GET & etc
     * @param url                     request URL
     * @param headers                 http headers
     * @param onEmptyResponseListener event for successful request (but no data return)
     * @param errorListener           event for failed request
     */
    public BaseRequest(int method, String url, Map<String, String> headers, OnEmptyResponseListener onEmptyResponseListener, ErrorListenerImpl errorListener)
    {
        super(method, url, errorListener);
        this.headers = headers;
        //noinspection unchecked
        listener = new OnEmptyResponseImpl(onEmptyResponseListener);
    }

    protected Response<T> parseNetworkResponse(NetworkResponse response)
    {

        // if response type is null so just pass null to success event
        if (this.responseType == null && new String(response.data).isEmpty())
        {
            return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
        }

        // if response type is specified
        try
        {
            Gson gson = new Gson();
            String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            // we use GSON to reflect response data to the generic type and pass to success event
            T parseObject = gson.fromJson(json, responseType);
            return Response.success(parseObject, HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e)
        {
            return Response.error(new ParseError(e));
        } catch (JsonSyntaxException e)
        {
            return Response.error(new ParseError(e));
        }
    }


    @Override
    protected void deliverResponse(T response)
    {
        if (listener != null)
        {
            // call successful response event when listener not empty
            listener.onResponse(response);
        }
    }

    @Override
    protected void onFinish()
    {
        super.onFinish();
        listener = null;
    }

    /**
     * this class forward response event to {@link com.khosravi.mehrdadz.garagesale.Network.RequestType.BaseRequest.OnEmptyResponseListener}
     * when volley {@link com.android.volley.Response.Listener} is called
     */
    private static class OnEmptyResponseImpl implements Response.Listener
    {
        OnEmptyResponseListener onEmptyResponseListener;

        /**
         * @param onEmptyResponseListener interface for response with not data return
         */
        public OnEmptyResponseImpl(OnEmptyResponseListener onEmptyResponseListener)
        {
            this.onEmptyResponseListener = onEmptyResponseListener;
        }

        /**
         * we call {@link com.khosravi.mehrdadz.garagesale.Network.RequestType.BaseRequest.OnEmptyResponseImpl#onEmptyResponseListener}
         * when volley listener is class so no null object passed to the event
         *
         * @param response
         */
        @Override
        public void onResponse(Object response)
        {
            onEmptyResponseListener.OnEmptyResponse();
        }
    }

    /**
     * interface for http response with no returning data
     */
    public interface OnEmptyResponseListener
    {
        void OnEmptyResponse();
    }

    public Map<String, String> getHeaders() throws AuthFailureError
    {
        return this.headers != null ? this.headers : super.getHeaders();
    }
}

这是GsonRequest类:

@SuppressWarnings("JavaDoc")
/**
 * Gson request that return generic type of response data
 * @param <T> the type of data for http responses
 */
public class GsonRequest<T> extends BaseRequest<T>
{
    protected static final String PROTOCOL_CHARSET = "utf-8";
    /**
     * Content type for request.
     */
    private static final String PROTOCOL_CONTENT_TYPE =
            String.format("application/json; charset=%s", PROTOCOL_CHARSET);

    /**
     * message body of http request
     */
    private final String requestBody;

    /**
     * Request return response object of Type {@link T}
     * @param url
     * @param headers
     * @param type
     * @param listener
     * @param errorListener
     */
    public GsonRequest(String url, Map<String, String> headers, Type type, Listener<T> listener, ErrorTypeListener errorListener)
    {
        super(Method.GET, url, headers, type, listener, new ErrorListenerImpl(errorListener));
        requestBody = null;
    }

    /**
     * Request return response object of Type {@link T}
     * @param url
     * @param headers
     * @param jsonObject json object to send with request
     * @param type
     * @param listener
     * @param errorListener
     */
    public GsonRequest(String url, Map<String, String> headers, JSONObject jsonObject, Type type, Listener<T> listener, ErrorTypeListener errorListener)
    {
        super(Method.POST, url, headers, type, listener, new ErrorListenerImpl(errorListener));
        this.requestBody = jsonObject == null ? null : jsonObject.toString();
    }

    /**
     * Request return empty response
     * @param url
     * @param headers
     * @param jsonObject json object to send with request
     * @param listener
     * @param errorListener
     */
    public GsonRequest(String url, Map<String, String> headers, JSONObject jsonObject, OnEmptyResponseListener listener, ErrorTypeListener errorListener)
    {
        super(Method.POST, url, headers, listener, new ErrorListenerImpl(errorListener));
        this.requestBody = jsonObject == null ? null : jsonObject.toString();
    }

    /**
     * Request return empty response
     * @param url
     * @param headers
     * @param listener
     * @param errorListener
     */
    public GsonRequest(String url, Map<String, String> headers, BaseRequest.OnEmptyResponseListener listener, ErrorTypeListener errorListener)
    {
        super(Method.GET, url, headers, listener, new ErrorListenerImpl(errorListener));
        requestBody = null;
    }


    @Override
    public String getBodyContentType()
    {
        return PROTOCOL_CONTENT_TYPE;
    }

    @Override
    public byte[] getBody()
    {
        try
        {
            return requestBody == null ? null : requestBody.getBytes(PROTOCOL_CHARSET);
        } catch (UnsupportedEncodingException uee)
        {
            VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
                    requestBody, PROTOCOL_CHARSET);
            return null;
        }
    }
}
public class MyRequest
{
public MyRequest(Context context)
    {
        volleySingleton = VolleySingleton.getInstance(context);
    }
private static final String INSERT_NEW_PIC = "INSERT_NEW_PIC";
public void UploadNewPic(File[] Images, BaseRequest.OnEmptyResponseListener listener, ErrorTypeListener errorListener)
    {

        FileUploadMultipartRequest fileUploadMultipartRequest = new FileUploadMultipartRequest("url", null, null, listener, errorListener,Images);
        volleySingleton.addToRequestQueue(fileUploadMultipartRequest, INSERT_NEW_PIC);
    }
}
MyRequest myRequest;
private HashMap<FrameLayout,File> Images;

myRequest = new MyRequest(context);
Images = new HashMap<>();

myRequest.UploadNewPic(Images.values().toArray(new File[Images.values().size()]),  new BaseRequest.OnEmptyResponseListener()
                    {
                        @Override
                        public void OnEmptyResponse()
                        {
                            Toast.makeText(getApplicationContext(), "added pics successfully", Toast.LENGTH_LONG).show();
                            finish();
                        }
                    }, new ErrorTypeListener()
                    {
                        @Override
                        public void onError(ErrorType errorType)
                        {

                        }
                    });
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
    {
        public CustomMultipartFormDataStreamProvider(string path) : base(path) { }


        //below only allows images and pdf files to be uploaded.
        public override Stream GetStream(HttpContent parent, System.Net.Http.Headers.HttpContentHeaders headers)
        {

            // following line handles other form fields other than files.
            if (String.IsNullOrEmpty(headers.ContentDisposition.FileName)) return base.GetStream(parent, headers);

            // restrict what filetypes can be uploaded
            List<string> extensions = new List<string> { "png", "gif",
                "jpg", "jpeg", "tiff", "pdf", "tif", "bmp","doc","docx","ods","xls","odt","csv","txt","rtf" };
            var filename = headers.ContentDisposition.FileName.Replace("\"", string.Empty); // correct for chrome.

            //make sure it has an extension
            if (filename.IndexOf('.') < 0)
            {
                return Stream.Null;
            }

            //get the extension
            var extension = filename.Split('.').Last();

            //Return stream if match otherwise return null stream.
            return extensions.Contains(extension) ? base.GetStream(parent, headers) : Stream.Null;

        }

        public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
        {
            var name = !string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName) ? headers.ContentDisposition.FileName : "NoName";
            name = name.Replace("\"", string.Empty);
            //name = (Guid.NewGuid()).ToString() +System.IO.Path.GetExtension(name); //this is here because Chrome submits files in quotation marks which get treated as part of the filename and get escaped

            name = Path.GetRandomFileName().Replace(".", string.Empty) + Path.GetExtension(name); //this is here because Chrome submits files in quotation marks which get treated as part of the filename and get escaped

            return name;
        }
    }
IRouteHandler
{

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        var filename = requestContext.RouteData.Values["filename"] as string;
        var section = requestContext.RouteData.Values["section"] as string;

        if (string.IsNullOrEmpty(filename) && string.IsNullOrEmpty(section))
        {
            // return a 404 HttpHandler here
            requestContext.HttpContext.Response.StatusCode = 404;
            requestContext.HttpContext.Response.End();
            return null;
        }

        requestContext.HttpContext.Response.Clear();
        requestContext.HttpContext.Response.Cache.SetMaxAge(TimeSpan.FromSeconds(500000));
        requestContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.Public);

        requestContext.HttpContext.Response.ContentType = GetContentType(filename);

        // find physical path to image here. 
        var path = GetPath(section);

        if (string.IsNullOrEmpty(path))
        {
            // return a 404 HttpHandler here
            requestContext.HttpContext.Response.StatusCode = 404;
            requestContext.HttpContext.Response.End();
            return null;
        }

        var filepath = requestContext.HttpContext.Server.MapPath(path + filename);
        requestContext.HttpContext.Response.WriteFile(filepath);
        requestContext.HttpContext.Response.End();
        return null;
    }

    private static string GetPath(string section)
    {
        switch (section)
        {
            case "user":
                return "~/Resources/Users/";//where you want save pics in project
        }
        return "";
    }


    private static string GetContentType(string path)
    {
        switch (Path.GetExtension(path))
        {
            case ".bmp":
                return "Image/bmp";
            case ".gif":
                return "Image/gif";
            case ".jpg":
                return "Image/jpeg";
            case ".png":
                return "Image/png";
        }
        return "";
    }
}
public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            // proccess all for protected resources with ImageRouteHandler
            routes.Add("ImagesRoute", new Route("res/{section}/{filename}", new ImageRouteHandler()));

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
public interface IUserManagement
    {
        void UploadNewPics( IEnumerable<string> imageUrls);
    }



    public class UserManagement : IUserManagement
    {
        public void UploadNewPics(IEnumerable<string> imageUrls)
        {

            using (var ctx = new Context())
            {

                foreach (var imageUrl in imageUrls)
                {
                    //save to data base
                    .
                    .
                    .
                }

                try
                {
                    ctx.SaveChanges();
                }
                catch (Exception e)
                {
                    throw;
                }
            }
        }
    }



        public class UserApiController : ApiController
{
    [HttpPost]
    public async Task<IHttpActionResult> UploadNewPics()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

        var root = HttpContext.Current.Server.MapPath("~/Resources/Users/");
        var provider = new CustomMultipartFormDataStreamProvider(root);
        try
        {
            // Read the form data.
            await Request.Content.ReadAsMultipartAsync(provider);

            IUserManagement userManagement = new UserManagement();

            var imageUrls = provider.FileData.Select(x=> Path.GetFileName(x.LocalFileName));
            //userManagement.UploadUserImage(uploadImageJson, Path.GetFileName(imageFile.LocalFileName), (long)imageFile.Headers.ContentLength);
            userManagement.UploadNewPics(imageUrls);
        }
        catch (Exception e)
        {
            return InternalServerError();
        }
        return Ok();
    }
}
 类似资料:
  • 问题内容: 我正在使用MultiPartRequester类将多部分图像上传到服务器,但是我发现其中的某些部分已被弃用。例如HttpConnectionParams,getConnectionManager()等,因此有人拥有不使用新API级别进行文件上传的新解决方案吗? 我正在使用此代码。 问题答案: 这是FileUploadMultipartRequest类: 这是BaseRequest类:

  • 由于中不推荐使用getExternalStoragePublicDirectory,建议使用其他方法。那么如何指定要将相机应用程序生成的照片存储到文件夹或中的自定义子文件夹? 文档中指出,以下3个选项是新的首选选项: 上下文#GetExternalFilesDir(字符串) 纵隔 意图#action_open_document 选项3也不是一个选择,因为它需要用户通过SAF文件资源管理器选择位置。

  • 我在最新的Android Studio上创建了一个全新的Android项目。我做的第一件事是将`realm'库添加到项目中,方法是将以下内容添加到gradle文件中: 如果我尝试编译,我会得到以下错误: Origine2:C:\users\usmaan.gradle\caches\caches\modules-2\files-2.1\io.realm\realm-android\0.80.3\79

  • 问题内容: 我已经看到了许多在API上使用注释以将其标记为“需要尽快替换”的示例。 但是,在几乎所有这些情况下,代码开发人员不仅继续使用已弃用的API,而且还抑制了弃用警告。 似乎API开发人员的最佳意图最终是创建更多与已实现的业务逻辑无关的代码- 如果不赞成使用API​​,但在抑制相关警告的情况下继续使用它,则似乎充其量只是代码的降级,并且在IMHO最差的情况下替换不推荐使用的库时,可能会导致应

  • 我在google上搜索onactivityresult()是不推荐的。但我的问题没有解决。下面是片段的代码

  • 例子有:本页和本页 有没有人有一个好的固体短的解决方案呢?