- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 MultiPartRequester 类将多部分图像上传到服务器,但我发现其中的某些部分已被弃用。例如 HttpConnectionParams 、 getConnectionManager() 等,所以任何人都有新的解决方案,不建议使用新的文件上传 API 级别?
我正在使用这个代码。
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");
}
}
最佳答案
这是 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)
{
}
});
服务器端代码(.net):
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;
}
}
公共(public)类 ImageRouteHandler :
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 "";
}
}
并像这样更改您的 RouteConfige:
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();
}
}
关于在新的 api 中不推荐使用 HttpConnectionParams 的 Android 多部分图像上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36513174/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!