使用Spring MVC实现ajax文件上传和MultipartFile

3

我在使用Spring 3 MVC的Ajax上传时遇到了问题。我理解我需要在Spring配置中配置multipartResolver bean,这我已经做到了。接下来,我可以有如下的控制器:

@RequestMapping(value ="/settingsSim")
@ResponseBody
public Map uploadSimSettings(@RequestParam(value="qqfile", required=true) MultipartFile settings) {
 Map<String, Object> ret = new HashMap<String, Object>();
 return ret;
}

问题在于,当我实际向服务器发送请求时(事实上,valums Ajax文件上传会替我执行此操作),我会收到一个内部服务器错误响应,并且日志中没有任何显示。我真的很困惑,因为我无法找出问题所在。


堆栈跟踪对于诊断问题非常有帮助。 - atrain
是的,这正是我在这里询问的主要原因,因为容器中没有任何堆栈跟踪信息。 - Tomáš Plešek
5个回答

3

我的解决方案:

@RequestMapping(value = "/create/upload", method = RequestMethod.POST, consumes="multipart/form-data", produces="application/json")
@ResponseBody()
public String handleImageUpload(@RequestParam(value="qqfile", required=true) MultipartFile[] files, 
        @ModelAttribute(value="files") List<MultipartFile> filesSession) throws IOException, FileUploadException {

    if (files.length > 0) {
        filesSession.addAll(Arrays.asList(files));
        // store the bytes somewhere
        return  "{\"success\": true}";
    }
    else {
        return "{\"success\": false}";
    }
}

@RequestMapping(value = "/create/upload", method = RequestMethod.POST, consumes="application/octet-stream", produces="application/json")
@ResponseBody()
public String handleImageUploadApplication(HttpServletRequest request, 
        @ModelAttribute(value="files") List<MultipartFile> filesSession) throws IOException, FileUploadException {

    if (request.getInputStream() != null) {
        // creamos el fichero temporal
        File file = File.createTempFile("file", "valumns",
                RepositoryData.getRepositoryData());
        FileOutputStream fos = new FileOutputStream(file);
        // copiamos contenido
        Streams.copy(request.getInputStream(), fos, true);
        //TODO: 
        //filesSession.addAll(Arrays.asList(files));
        // store the bytes somewhere
        return  "{\"success\": true}";
    }
    else {
        return  "{\"success\": true}";
    }
}

@ExceptionHandler(Exception.class)
@ResponseStatus(value = HttpStatus.SERVICE_UNAVAILABLE)
public void handleException(Exception ex) {
    log.error("Ocurrio un error en el album", ex);
}

2

我曾经遇到过与fineuploader (valums)相同的问题,尝试使用request.getInputStream()但是没有成功。

@ResponseBody注解可以工作,但是我得到了带有头部信息的整个内容。我认为处理这些内容并去除不需要的块并不十分优雅。我进一步查找并在这篇文章中找到了解决方案:

problem with spring ajax file upload

如所述,我将multipart解析器的bean配置添加到我的spring配置中。

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>

之后,我可以使用_____轻松检索我的文件。

 public @ResponseBody Map ajaxUploadFile(@RequestParam MultipartFile qqfile) { ... }

不要忘记在您的项目中添加Apache commons-io.jarcommons-fileupload.jar库来使其正常工作。


1

当使用valums插件时,我通过使用@RequestBody Spring注释解决了这个问题。 您可以按照以下方式重写您的代码:

@RequestMapping(value ="/settingsSim",method=RequestMethod.POST)
@ResponseBody
public Map uploadSimSettings(@RequestBody String body) {
 /*
 some controller logic 
 */
}

请注意,变量body将包含上传文件的内容。此外,在您的示例中没有方法声明,这意味着您的方法将映射到GET请求。
附注:当使用Apache Commons解析请求时,我也遇到了“无多部分边界”问题。HttpServletRequest#getParts()仅返回一个空集合。

1

@Tomas 我在使用同一jQuery插件时遇到了相同的问题。请将插件代码中的Content-Type更改为xhr.setRequestHeader("Content-Type", "multipart/form-data"); 在我的插件上是第1203行,更改后它现在显示一个堆栈跟踪,但是我遇到了另一个问题,即日志打印: Sep 8, 2011 9:43:39 AM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet dispatcher threw exception org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found


1
根据我的观察,文件上传插件没有发送多部分文件,而是发送了一个流。我可以通过声明控制器方法接受文件名作为请求参数qqfile和第二个参数作为httprequest来使其工作。然后我使用request.getinputstream进行进一步处理。希望这有所帮助!
敬礼,
Pradyumna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接