通过REST API进行多部分文件上载会破坏文件并增加文件大小

时间:2017-01-30 05:41:45

标签: java file-upload multipartform-data filesize

将文件(任何格式的doc,docx,pdf,text等)作为多部分表单/数据从Postman或应用程序UI上传到REST API。文本文件上传很好。所有其他非文本格式都已损坏。我无法打开这些文件。

上传文件的大小急剧增加。检查以下服务器日志:

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

上传文件的大小为27.3Kb

我猜测文件因为附加到文件中的其他数据而被破坏。

控制器方法是

@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

由于文本文件正确保存且其他文件也正确编写,因此不要认为编写该文件的代码不正确。

获取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;
    }

我的Ajax请求如下

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)

上传时的内容类型:

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

有谁知道如何解决此问题并成功上传文件?

Q1)为什么请求调度程序和处理文件数据的控制器之间的文件大小会发生变化。

Q2)文件大小的这种变化是否会导致文件损坏? Libre Office导致一般输入/输出错误。

2 个答案:

答案 0 :(得分:1)

我想到了文件上传的问题。我之间有一个spring过滤器,它将请求更改为wrappedRequest。这会向多部分数据添加额外数据并导致文件损坏。

答案 1 :(得分:0)

在我的情况下,通过Amazon API Gateway访问API时,我遇到了完全相同的问题。原来我忘了在API网关上允许多部分ContentType。 奇怪的是,这些请求仍然可以发送到我的服务器,文本文件也可以正常工作。