我使用Retrofit v.2.2.0将图片上传到我的服务器,但服务器返回一个空值,表示没有上传图片。日志显示上传图像,上传时文件名正确。什么可能是问题,但它在邮递员工作?
UploadProfilePicture.java
public class UploadProfilePicture extends ContextWrapper {
private GetOnUpload onUpload;
private File imageFile,filesDir,file;
private Uri fileUri;
private String profilePic = "profile_pic";
private String fileName;
private ParcelFileDescriptor parcelFileDescriptor;
private FileDescriptor fileDescriptor;
private Bitmap profileImage;
private OutputStream os;
private OkHttpLogClientAPI okHttpLogClientAPI;
private GetOnUpload mInterfaceService;
public UploadProfilePicture(Context base) {
super(base);
okHttpLogClientAPI = new OkHttpLogClientAPI(getBaseContext());
mInterfaceService = okHttpLogClientAPI.logger().create(GetOnUpload.class);
}
public void uploadPic(Uri fileUri,String fileName, final OnSetUploadProfilePic setOnUpload) {
//Build Req estBodies for the map object and a MultipartBody.Part to encapsulate the prof_pic_drawer
this.fileUri = fileUri;
this.fileName = fileName;
try {
getBitmapFromUri();
} catch (IOException e) {
e.printStackTrace();
}
file = persistImage();
RequestBody finalRequestBody = builder.build();
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), getBytesFromBitmap(profileImage));
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("file", "avatar.jpg", requestFile);
Call<ResponseUserModel> call = mInterfaceService.upload(body);
call.enqueue(new Callback<ResponseUserModel>() {
@Override
public void onResponse(Call<Response> call, Response<Response> response) {
if (response.isSuccessful()) {
setOnUpload.uploadMessage(response.body());
} else {
Toast.makeText(getBaseContext(), getString(R.string.failed_to_upload), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<Response> call, Throwable t) {
Toast.makeText(getBaseContext(), getString(R.string.failed_to_upload), Toast.LENGTH_SHORT).show();
}
});
}
}
public static byte[] getBytesFromBitmap(Bitmap bitmap) {
if (bitmap!=null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
return stream.toByteArray();
}
return null;
}
private MultipartBody.Part prepareFilePart() {
//TODO: Use FileUtils to get the actual file by uri
try {
getBitmapFromUri();
file = persistImage();
} catch (IOException e) {
e.printStackTrace();
}
try {
RequestBody requestFile = RequestBody.create(
MediaType.parse(getBaseContext().getContentResolver().getType(fileUri)), file);
return MultipartBody.Part.createFormData("file", file.getName(), requestFile);
} catch (NullPointerException e) {
Toast.makeText(getBaseContext(), "" + e.getMessage(), Toast.LENGTH_SHORT).show();
return null;
}
}
private RequestBody createPartFromString(String descriptionString) {
return RequestBody.create(MultipartBody.FORM, descriptionString);
}
private void getBitmapFromUri() throws IOException {
profileImage = MediaStore.Images.Media.getBitmap(this.getContentResolver(), fileUri);
}
private File persistImage() {
filesDir = getFilesDir();
imageFile = new File(filesDir, fileName + ".jpg");
OutputStream os;
try {
os = new FileOutputStream(imageFile);
profileImage.compress(Bitmap.CompressFormat.JPEG, 70, os);
os.flush();
os.close();
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
}
return imageFile;
}}
GetOnUpload.java
public interface GetOnUpload {
@Multipart
@POST(Constants.UPLOAD_URL)
Call<Response> upload(@Part MultipartBody.Part file);}
日志
http://local.com/api/v1/avatar http / 1.1 11-14 18:40:02.742 8851-9593 / com.local.test D / OkHttp:Content-Type:multipart / form-data;边界= d43da080-f2c3-4743-8cfd-9526cc0bd2f7 11-14 18:40:02.742 8851-9593 / com.local.test D / OkHttp:内容长度:12424 11-14 18:40:02.743 8851-9593 / com.local.test D / OkHttp: - d43da080-f2c3-4743-8cfd-9526cc0bd2f7 11-14 18:40:02.743 8851-9593 / com.local.test D / OkHttp:Content-Disposition:form-data;命名=&#34;文件&#34 ;;文件名=&#34; avatar.jpg&#34; 11-14 18:40:02.743 8851-9593 / com.local.test D / OkHttp:Content-Type:multipart / form-data 11-14 18:40:02.743 8851-9593 / com.local.test D / OkHttp:内容长度:12201 11-14 18:40:02.743 8851-9593 / com.local.test D / OkHttp: 11-14 18:40:02.744 8851-9593 / com.local.test D / OkHttp: - d43da080-f2c3-4743-8cfd-9526cc0bd2f7-- 11-14 18:40:02.744 8851-9593 / com.local.test D / OkHttp: - &gt; END POST(12424字节正文)
11-14 18:40:03.332 8851-9593 / com.local.test D / OkHttp:&lt; - 200 OK http://local.com/api/v1/avatar(587ms) 11-14 18:40:03.332 8851-9593 / com.local.test D / OkHttp:服务器:nginx / 1.10.3(Ubuntu) 11-14 18:40:03.332 8851-9593 / com.local.test D / OkHttp:Content-Type:application / json 11-14 18:40:03.332 8851-9593 / com.local.test D / OkHttp:Transfer-Encoding:chunked 11-14 18:40:03.332 8851-9593 / com.local.test D / OkHttp:连接:保持活着 11-14 18:40:03.332 8851-9593 / com.local.test D / OkHttp:Cache-Control:no-cache,private 11-14 18:40:03.332 8851-9593 / com.local.test D / OkHttp:日期:星期二,2017年11月14日15:40:03 GMT 11-14 18:40:03.332 8851-9593 / com.local.test D / OkHttp:X-RateLimit-Limit:60 11-14 18:40:03.332 8851-9593 / com.local.test D / OkHttp:X-RateLimit-Remaining:59 11-14 18:40:03.333 8851-9593 / com.local.test D / OkHttp:{&#34;用户&#34;:&#34;失败&#34;,&#34;状态&#34;:& #34;图片文件未上传&#34;}
答案 0 :(得分:1)
这个例子对我有用
//My data manager
public void doUpload(
Context context,
String url) {
Uri uri = Uri.parse(url);
File file = new File(getPath(context, uri));
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("imageParameterName", file.getName(), reqFile);
uploadService(body)
}
//REST service
@Multipart
@POST("upload.aspx")
Call<DefaultDTO> uploadService(@Part MultipartBody.Part image);
答案 1 :(得分:1)
似乎OKHttp存在问题,因此在通过改造将文件和数据发布到服务器时使用此格式
file = new File(fileUri.getPath());
RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"),file);
RequestBody dataBody = RequestBody.create(MediaType.parse("text/plain"), "id");
Call<Response> call = mInterfaceService.upload(fileBody,dataBody);
call.enqueue(new Callback<Response>() {
@Override
public void onResponse(Call<Response> call, Response<Response> response) {
if (response.isSuccessful()) {
setOnUpload.uploadMessage(response.body());
if(file.exists())
file.delete();
} else {
Toast.makeText(getBaseContext(), getString(R.string.failed_to_upload), Toast.LENGTH_SHORT).show();
}
}
public interface GetOnUpload {
@Multipart
@POST(Constants.UPLOAD_URL)
Call<Response> upload(@Part("file\";filename=\"avatar.jpg\" ") RequestBody file,@Part("id")RequestBody user);
}
答案 2 :(得分:0)
<强> ImageFilePath 强>
@SuppressLint("NewApi")
@TargetApi(Build.VERSION_CODES.KITKAT)
public class ImageFilePath {
/**
* Method for return file path of Gallery image
*
* @param context
* @param uri
* @return path of the selected image file from gallery
*/
static String nopath = "Select Video Only";
@TargetApi(Build.VERSION_CODES.KITKAT)
@SuppressLint("NewApi")
public static String getPath(final Context context, final Uri uri) {
// check here to KITKAT or new version
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/"
+ split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] { split[1] };
return getDataColumn(context, contentUri, selection,
selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return nopath;
}
/**
* Get the value of the data column for this Uri. This is <span id="IL_AD2"
* class="IL_AD">useful</span> for MediaStore Uris, and other file-based
* ContentProviders.
*
* @param context
* The context.
* @param uri
* The Uri to query.
* @param selection
* (Optional) Filter used in the query.
* @param selectionArgs
* (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri,
String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = { column };
try {
cursor = context.getContentResolver().query(uri, projection,
selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return nopath;
}
/**
* @param uri
* The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri
.getAuthority());
}
/**
* @param uri
* The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri
.getAuthority());
}
/**
* @param uri
* The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri
.getAuthority());
}
/**
* @param uri
* The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri
.getAuthority());
}
}
<强> ChooseImg 强>
private void openChooseImgDialog() {
Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
getIntent.setType("image/*");
Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.setType("image/*");
Intent chooserIntent = Intent.createChooser(getIntent, "Select Image");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent});
startActivityForResult(chooserIntent, PICK_IMAGE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case PICK_IMAGE:
if (resultCode == Activity.RESULT_OK) {
uri = data.getData();
File_Path = ImageFilePath.getPath(getActivity(), data.getData());
// File_Path = RealPathUtil.getRealPathFromURI_API19(getActivity(), data.getData());
// String filename = uri.getLastPathSegment();
Log.d("displayfiletypes","**** "+data.getData() + " "+File_Path);
tv_feedbackfilename.setText(File_Path.substring(File_Path.lastIndexOf("/")+1));
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), uri);
// Log.d(TAG, String.valueOf(bitmap));
// mImgView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getActivity(), "Something Went Wrong", Toast.LENGTH_SHORT).show();
}
break;
}
}
<强>接口强>
@Multipart
@POST("url")
Call<ResponseBody> add_feedback(@Part MultipartBody.Part file);
在您的活动中添加此代码
Retrofit adapter = new Retrofit.Builder()
.baseUrl(Constandapi.ROOT_URL)
.build();
RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), file);
MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("your php file key", file.getName(), requestBody);
Call<ResponseBody> adding_feedback = addfeedback.add_feedback(auth_key_sent, subjectstring_sent, feedbackmsg_sent, fileToUpload);
adding_feedback.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful())
{
progressDialog.dismiss();
String result = null;
try{
result = response.body().string();
Log.d("createddates","responce"+result);
}catch (IOException e){
e.printStackTrace();
}catch (JSONException jsone){
jsone.printStackTrace();
}
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getActivity(), "Please try after sometime", Toast.LENGTH_SHORT).show();
Log.d("printmessages","*** "+call.toString() + " "+t.toString());
progressDialog.dismiss();
}
});