我正在尝试将图像上传到servlet,但是在自动化测试期间,它会无声地失败。
你们知道会导致什么原因吗?
以下是服务器上的代码:
@ResponseBody
@RequestMapping(method = RequestMethod.POST)
public String upload(HttpServletRequest request) throws Exception {
BufferedImage image = null;
@SuppressWarnings("unchecked")
List<FileItem> items = new ServletFileUpload(
new DiskFileItemFactory()).parseRequest(request);
Logger.log(LogLevel.INFO, "Upload contains " + items.size()
+ " items.");
int i = 0;
for (FileItem item : items) {
Logger.log(LogLevel.INFO, "\tItem " + (i++) + ". Name:\t"
+ item.getName() + ", Type:\t" + item.getContentType());
// File is of type "file"
if (!item.isFormField()) {
InputStream inputStream = null;
try {
inputStream = item.getInputStream();
if (inputStream.available() == 0) {
Logger.log(LogLevel.WARN,
"Item shows file type, but no bytes are available");
}
image = ImageIO.read(inputStream);
if (image != null) {
break;
}
} catch (Exception e) {
Logger.log(LogLevel.ERROR,
"There was an error reading the image. "
+ ExceptionUtils.getFullStackTrace(e));
throw new Exception("image provided is not a valid image");
} finally {
if (inputStream != null) {
IOUtils.closeQuietly(inputStream);
}
}
}
}
if (image == null) {
Logger.log(LogLevel.ERROR, "Image was supposedly read correctly, but was null afterwards");
throw new Exception("Image provided could not be read");
}
//do stuff with image
...
}
以下是测试:
public void testImageUpload throws Exception {
HttpPost httppost = new HttpPost("path/to/endpoint");
File file=new File(imgLoc);
FileBody bin = new FileBody(file);
StringBody comment = new StringBody("Filename: " + file);
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("upload-file", bin);
reqEntity.addPart("comment", comment);
httppost.setHeader("Accept", "application/json");
httppost.setHeader("Connection","Keep-Alive");
httppost.setEntity(reqEntity);
HttpResponse response =testClient.getClient().execute(httppost);
imgResponse=response.getStatusLine().toString();
System.out.println(imgResponse);
BufferedReader reader = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
String line;
while ((line = reader.readLine()) != null){
output = output + " " +line;}
System.out.println("Image Response: "+output);
}
以下是服务器失败时的输出:
2013/10/02 05-53-32,287::LOG:INFO[com.example#upload:L130 -- Upload contains 2 items.]
2013/10/02 05-53-32,288::LOG:INFO[com.example#upload:L133 -- Item 0. Name: Dog.jpg, Type: application/octet-stream]
2013/10/02 05-53-32,288::LOG:WARN[com.example#upload:L140 -- Item shows file type, but no bytes are available]
2013/10/02 05-53-32,289::LOG:INFO[com.example#upload:L133 -- Item 1. Name: null, Type: text/plain; charset=ISO-8859-1]
2013/10/02 05-53-32,290::LOG:ERROR[com.example#upload:L159 -- Image was supposedly read correctly, but was null afterwards]
我们从图片上传中捕获异常并将响应代码422发送回客户端,因此在测试中,我们得到imgResponse
== 422这是一个失败案例。
注意:这只会发生有时您运行测试。
答案 0 :(得分:2)
以下是使用Apache Commons FileUpload进行文件上传的分步配置:
<强> 1。为以下组件添加依赖项jar。以下是maven依赖项:
的pom.xml
<dependencies>
<!-- Spring 3 MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<!-- Apache Commons file upload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<!-- Apache Commons IO -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<!-- JSTL for c: tag -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
如果您不使用maven,请在线下载maven存储库中的相应jar。
<强> 2。创建FileUploadForm模型
FileUploadForm.java
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
public class FileUploadForm {
private List<MultipartFile> files;
//Getter and setter methods
}
第3。将解析程序添加到MVC配置文件
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="100000"/>
</bean>
<强> 4。写FileUploadController
FileUploadController.java
@Controller
public class FileUploadController {
@RequestMapping(value = "/show", method = RequestMethod.GET)
public String displayForm() {
return "file_upload_form";
}
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(
@ModelAttribute("uploadForm") FileUploadForm uploadForm,
Model map) {
List<MultipartFile> files = uploadForm.getFiles();
List<String> fileNames = new ArrayList<String>();
if(null != files && files.size() > 0) {
for (MultipartFile multipartFile : files) {
String fileName = multipartFile.getOriginalFilename();
fileNames.add(fileName);
//Handle file content - multipartFile.getInputStream()
}
}
map.addAttribute("files", fileNames);
return "file_upload_success";
}
}
<强> 5。写jsp视图
file_upload_form.jsp
<html>
<head>
<title>Spring MVC Multiple File Upload</title>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
//add more file components if Add is clicked
$('#addFile').click(function() {
var fileIndex = $('#fileTable tr').children().length - 1;
$('#fileTable').append(
'<tr><td>'+
' <input type="file" name="files['+ fileIndex +']" />'+
'</td></tr>');
});
});
</script>
</head>
<body>
<h1>Spring Multiple File Upload example</h1>
<form method="post" action="save.html"
**enctype="multipart/form-data"**>
<p>Select files to upload. Press Add button to add more file inputs.</p>
<input id="addFile" type="button" value="Add File" />
<table id="fileTable">
<tr>
<td><input name="files[0]" type="file" /></td>
</tr>
<tr>
<td><input name="files[1]" type="file" /></td>
</tr>
</table>
<br/><input type="submit" value="Upload" />
</form>
</body>
</html>
答案 1 :(得分:0)
您的内容类型似乎是application / octet-stream。请在您的请求中添加以下标题,然后尝试
("Content-Type", "multipart/form-data");
答案 2 :(得分:0)
您正在使用InputStream#available。正如文档所述,这是可以从流中读取而不阻塞的字节数。现在,TCP输入流可用的字节数取决于数据包的大小以及请求如何在其中切分(以及更多其他因素)。
如果您的目的是始终完整阅读流,请忘记available()
方法,只需将其读出直到流结束,您就可以了。
答案 3 :(得分:0)
我之前在两个条件下遇到过这种情况。曾经是我在磁盘空间不足的时候,另一个是在我做一些负载测试的时候。
如果您查看How it works页面,可以将工具转储到磁盘或将其保留在内存中。在一个案例中,我在测试期间填满了驱动器,另一个我将物品保存在内存中,但是负载损坏了我的内存限制。
你是如何设置的?你用来测试的图像有多大?你在测试期间上传了多少次?有了这些信息,我应该能够提供更多帮助。
答案 4 :(得分:0)
此代码目前在我的网站上使用,就像一个魅力:
package com.example;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
@Controller
@RequestMapping("/api/media")
public class ImageRestService {
private static final Logger LOG = LoggerFactory.getLogger(ImageRestService.class);
@RequestMapping(value = "/uploadtemp", method = RequestMethod.POST)
public String upload(@RequestParam(value = "image") MultipartFile image) {
try {
BufferedImage bufferedImage = ImageIO.read(image.getInputStream());
// process image here
} catch (IOException e) {
LOG.error("failed to process image", e);
return "failure/view/name";
}
return "success/view/name";
}
}
答案 5 :(得分:-1)
项目列表的顺序可能不固定(取决于时间?)。你的代码
if (image != null) {
break;
}
退出循环而不是尝试下一部分。在评论中你声明我们遍历文件,直到我们可以解析一个,这应该是
if (image != null) {
continue;
}
然后