Sonal Sonal - 4 years ago 139
Java Question

Multipart File Upload via REST API corrupts file and increases file size

Am uploading a file (any format doc, docx, pdf, text, etc) as multipart form/data to a REST API from Postman or application UI. The text file uploads fine. All other non-text formats get corrupted. I cant open those files.

The size of the uploaded file increases drastically. Check the following server log:

File size just before call to request.getRequestDispatcher().forward(): 27583
Controller, first line in method:39439


The size of the uploaded file is 27.3Kb

I am guessing the files gets corrupted because of the other data appended to the file.

Controller method is

@RequestMapping(value="/entity/{entity}/{entityId}/type/{type}/{derive}",method = RequestMethod.POST)
@ResponseBody
public String uploadFile(@RequestParam("file") MultipartFile multipartFile,@PathVariable("entity")String entity,@PathVariable("type")String type,@PathVariable("entityId")Long entityId,@PathVariable("derive") boolean derive) throws Exception


Since text file is saving correctly and other files also get written correctly, don't think the code to write the file is incorrect.

Code to get inputStream

public String storeFile(MultipartFile multipartFile, String entity, Long id, String uploadType, boolean isDerive,String customName)
throws Exception
{
try
{
System.out.println(multipartFile.getSize());
String fileName = "";
String contentType = "";
if (multipartFile != null)
{
fileName = multipartFile.getOriginalFilename();
contentType = multipartFile.getContentType();
if (contentType == null)
{
contentType = "application/msword";
}
}
InputStream is = multipartFile.getInputStream();
String filePath = getFileName(entity, uploadType, id, fileName, isDerive,customName);
Helper.storeFile(is, filePath);
precedingPath = precedingPath.length() > 0 ? precedingPath + "/":"";
return precedingPath + filePath;
}
catch (WebException e)
{
e.printStackTrace();
throw e;
}
catch (Exception e)
{
e.printStackTrace();
throw new WebException(e.getMessage(), IHttpConstants.INTERNAL_SERVER_ERROR, e);
}
}


Helper.storeFile

public static File storeFile(InputStream is, String filePath) throws IOException {
try {
String staticRepoPath = null;

if (MasterData.getInstance().getSettingsMap().containsKey(Settings.REPO_LOCATION.toString())) {
staticRepoPath = MasterData.getInstance().getSettingsMap().get(Settings.REPO_LOCATION.toString());
} else {
throw new WebException("Invalid Settings");
}

byte[] buffer = new byte[is.available()];
is.read(buffer);

File targetFile = new File(staticRepoPath + File.separator + filePath);
@SuppressWarnings("resource")
OutputStream outStream = new FileOutputStream(targetFile);
outStream.write(buffer);
return targetFile;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}


My Ajax request is as follows

var fd = new FormData();
//Take the first selected file
fd.append("file", document.actualFile);
//Generic AJAX call
CandidateService.ajax_uploadDocumentWithDocType($scope.candidate.id, fd, document.docType, function (error, json)


Content type while uploading:

var config = {headers:{'X-Auth-Token':authToken, 'Content-Type': undefined}, transformRequest: angular.identity};


Would anyone know how I can fix this and upload the file successfully?

Q1) Why does the file size change between the request dispatcher and the controller that handles the file data.

Q2) Could this change of file size be the cause of file corruption? Libre Office cause General Input/Output Error.

Answer Source

I figured the problem with the file upload. I had a spring filter in between that was changing the request to a wrappedRequest. This was adding additional data to the multipart data and causing the file to be corrupted.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download