2017-08-15 31 views
0

,首先讓我們看看到代碼:上傳圖片到服務器使用改裝2

public interface ApiInterface { 
    @Multipart 
    @POST("my/files/photo/") 
    Call<FileUploadResponse> uploadPhoto(@Header("authorization") String auth, 
            @Part MultipartBody.Part file, 
            @Part("file-type") RequestBody fileType); 
} 

我打電話這個接口是這樣的:

RequestBody body = RequestBody.create(MediaType 
      .parse(getContentResolver().getType(fileUri)), file); 
MultipartBody.Part avatarBody = MultipartBody.Part 
      .createFormData(data, file.getName(), body); 
RequestBody fileType = RequestBody.create(
      MediaType.parse("text/plain"), "profile"); 
client.uploadPhoto(getToken(), avatarBody, fileType); 

從服務器我得到應答「未提供文件類型」。如果我更改文件和文件類型的地方上uploadPhoto功能是這樣的:

@Multipart 
@POST("my/files/photo/") 
Call<FileUploadResponse> uploadPhoto(@Header("authorization") String auth, 
           @Part("file-type") RequestBody fileType 
           @Part MultipartBody.Part file); 

我得到「沒有提供文件」的迴應。 我檢查服務器與我自己寫的JS代碼:

<!DOCTYPE html> 
 
<script language="JavaScript" type="text/javascript" src="C://Users/User/Downloads/jquery-3.2.1.min.js"></script> 
 

 
<form action=""> 
 
    <input type="text" name="authorize" id="authorize"> 
 
    <br> 
 
    <input type="file" name="photo" accept="image/*" id="filechooser" onchange="onFileChange(this)" > 
 
    <br> 
 
    <input value="profile" type="text" name="file-type" id="type"> 
 
    <br> 
 
    <input type="button" onclick="uploadFile()"> 
 
</form> 
 

 

 
<script> 
 
var blobFile; 
 
function onFileChange(ss) { 
 
\t blobFile = ss.files[0]; 
 
\t alert(blobFile); 
 
} 
 
function uploadFile() { 
 

 
\t var storedJWT = $('#authorize').val(); 
 
\t var fileType = $('#type').val(); 
 
    var formData = new FormData(); 
 
    formData.append("file-type", fileType); 
 
\t formData.append("photo", blobFile); 
 
\t console.log(storedJWT); 
 
    $.ajax({ 
 
     url: "url", 
 
     type: "POST", 
 
     data: formData, 
 
\t headers: { 
 
     authorization: storedJWT 
 
\t }, 
 
     processData: false, 
 
     contentType: false, 
 
     success: function(response) { 
 
\t \t console.log(response); 
 
     }, 
 
     error: function(jqXHR, textStatus, errorMessage) { 
 
      console.log(errorMessage); 
 
     } 
 
    }); 
 
}</script>

一切工作正常。在這樣的JS生成請求腳本:

Accept:*/* 
Accept-Encoding:gzip, deflate 
Accept-Language:en-US,en;q=0.8 
authorization:JWT token 
Connection:keep-alive 
Content-Length:67601 
Content-Type:multipart/form-data; boundary=---- 
WebKitFormBoundary3MtpMA70hG41luF1 
Host:localhost 
------WebKitFormBoundary3MtpMA70hG41luF1 
Content-Disposition: form-data; name="file-type" 

profile 
------WebKitFormBoundary3MtpMA70hG41luF1 
Content-Disposition: form-data; name="photo"; filename="1231231313.jpg" 
Content-Type: image/jpeg 


------WebKitFormBoundary3MtpMA70hG41luF1-- 

和改造的要求是:

Content-Type: multipart/form-data; boundary=238182ad-d99c-4d44-9ba6-7d178a14b2e9 
Content-Length: 59776 
authorization: JWT token 
--238182ad-d99c-4d44-9ba6-7d178a14b2e9 
Content-Disposition: form-data; name="photo"; filename="1502703422332.jpg" 
Content-Type: image/jpeg 
Content-Length: 59369 
//bytes 
--238182ad-d99c-4d44-9ba6-7d178a14b2e9 
Content-Disposition: form-data; name="file-type" 
Content-Transfer-Encoding: binary 
Content-Type: text/plain; charset=utf-8 
Content-Length: 7 
profile 
--238182ad-d99c-4d44-9ba6-7d178a14b2e9-- 

我能不明白的地方可以是錯誤...

回答

0

很多搜​​索後,我發現,服務器不處理標題,如

Content-Transfer-Encoding: binary 
Content-Type: text/plain; charset=utf-8 

我必須從我的請求中刪除這些標頭。解決的辦法是在我的API接口創建上傳功能是這樣的:

@POST("my/files/photo/") 
    Call<FileUploadResponse> uploadPhoto(@Header("Content-Type") String contentType, 
              @Header("Authorization") String auth, 
              @Body MultipartBody body); 

,並調用這樣的功能:

ApiClient.ApiInterface client = ApiClient.getClient(); 
File file = new File(getPathFromUri(fileUri)); 
RequestBody fileBody = RequestBody.create(MediaType.parse(getContentResolver().getType(fileUri)), file); 
MultipartBody body = new MultipartBody.Builder().addFormDataPart("file-type", "profile") 
       .addFormDataPart("photo", "image.png", fileBody) 
       .build(); 
client.uploadPhoto("multipart/form-data; boundary=" + body.boundary(), 
        PrefManager.getInstance().getToken(), body); 

至於結果我得到以下要求:

Content-Type: multipart/form-data; boundary=27ec8d66-d29d-48aa-a2fe-08c6664b10c7 
Content-Length: 56412 
Authorization: JWT token 
--27ec8d66-d29d-48aa-a2fe-08c6664b10c7 
Content-Disposition: form-data; name="file-type" 
Content-Length: 7 
profile 
--27ec8d66-d29d-48aa-a2fe-08c6664b10c7 
Content-Disposition: form-data; name="photo"; filename="image.png" 
Content-Type: image/jpeg 
Content-Length: 56089 
/* bytes */ 
--27ec8d66-d29d-48aa-a2fe-08c6664b10c7-- 

它工作正常。