android - 如何正确使用 Retrofit 从 Android 设备上传文件到 Laravel 服务器
问题描述
我正在尝试使用 Retrofit2 Multipart 编码将图像从 Android Studio 上传到 Laravel 服务器,但我不断收到“500 Internal Server Error”,这意味着服务器端可能出现问题,但我无法确定它是什么.
这是我的接口调用(Android Studio):
@Multipart
@POST("public/imagem")
Call<ResponseBody> uploadImagem(@Part MultipartBody.Part part,
@Part("name") RequestBody name,
@Part("animal_id") long animal_id,
@Part("ativo") int ativo);
这是请求(Android Studio):
//Create a file object using file path
File file = new File(filePath);
// Create a request body with file and image media type
RequestBody fileReqBody = RequestBody.create(MediaType.parse("image/*"), file);
// Create MultipartBody.Part using file request-body,file name and part name
MultipartBody.Part part = MultipartBody.Part.createFormData("upload", file.getName(), fileReqBody);
//Create request body with text description and text media type
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "image-type");
WebService.getInstance().getService().uploadImagem(part, name, animal_id, 1).enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
//THIS IS WHERE I WANT TO GET
} else {
//THIS IS WHERE IM GETTING AT EVERYTIME
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
这是我的路线(Laravel):
Route::post('imagem','ImagemController@createImagem');
这是“ImagemController”(Laravel)中的“createImagem”函数:
public function createImagem(Request $request){
$destinationPath = url('/midia'); //i have a "midia" folder inside "public" folder
$image = $request->file('part');
$name = $request->input('name');
$image->move($destinationPath, $name);
$dbPath = $destinationPath. '/'.$name;
$imagem = new Imagem();
$imagem->animal_id = $request->input('animal_id');
$imagem->img_url = $dbPath;
$imagem->ativo = $request->input('ativo');
$imagem->save();
return response()->json($imagem);
}
但我收到 500 Internal Server Error,所以服务器端的某些东西可能不符合逻辑上的正确性,你能帮我找出我的代码中有什么问题吗?
附言。我确实对此服务器有其他功能齐全的请求,但它们都只是字段,而这有一个文件,需要多部分编码,与其他请求不同。
编辑:这是服务器错误日志:
[2019-06-11 21:21:03] local.ERROR: Call to a member function move() on null {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Call to a member function move() on null at /.../Controllers/ImagemController.php:28)
所以看来我无法获取文件
$image = $request->file('part');
解决方案
我认为错误可能是因为路径必须是路径而不是 url:
$destinationPath = url('/midia');
如果要将文件移动到公用文件夹,则必须使用public_path()
路径:
$image = $request->file('part');
$destinationPath = 'midia';
$name = $request->input('name') .'.'. $image->getClientOriginalExtension();
$image->move(public_path($destinationPath), $name);
如果您想在请求中没有图像时避免错误并且不浪费服务器资源,请在函数开头添加验证:
public function createImagem(Request $request){
$this->validate($request, [
'part' => 'required|image|max:2048',
// other fields validations
]);
// the createImagem logic here
}
如果验证失败,您将不会尝试移动文件并且也不会查询数据库,那么正确的错误响应将自动发送回您可以处理的客户端。
推荐阅读
- python - For循环根据csv python中的列名创建标题
- python - 如何使用 exec() 在字符串函数中使用内置模块
- javascript - undefined 不是对象(评估 '_this.el')
- twitter-bootstrap - Bootstrap 模态文本右对齐
- python - 如何使用if条件更改python中的变量值
- python - 在 VS 代码中调试 Python 脚本时出现无法识别的参数错误
- json - 如何在 Python 2.7 中有效地解析具有多个键的 JSON 数据?
- selenium - 在 Selenium WebDriver 中获取 java.lang.NullPointerException
- java - 未安装提供程序“gs”
- powershell - 希望通过 csv 文件使用 PowerShell 进行查找和替换