我需要在Spring MVC中创建一个可以处理JSON和Multipart Form请求的方法。
这是我方法的签名:
@RequestMapping(value = { "/upload_image" }, method = RequestMethod.POST)
public @ResponseBody void uploadImage(final ImageDTO image)
ImageDTO类如下所示:
public class ImageDTO {
private String imageUrl;
private Long imageId;
private MultipartFile image;
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(final String url) {
this.imageUrl = url;
}
public Long getImageId() {
return imageId;
}
public void setImageId(final Long imageId) {
this.imageId = imageId;
}
public MultipartFile getImage() {
return image;
}
public void setImage(MultipartFile image) {
this.image = image;
}
}
所以情况是我需要支持两种情况: 1.从表单加载图像,其中Content-Type是多部分形式(所有DTO成员都不为空) 2.使用JSON进行图像上传,仅使用imageUrl。 在这种情况下,请求正文如下所示:
{
"imageId":"1236",
"imageUrl":"http://some.image.url",
"image":null
}
当前实现很好地处理了多部分请求,但是在发送JSON时,ImageDTO对象在其所有成员中都包含NULL。
是否可以使同一方法处理两种内容类型?
谢谢。
答案 0 :(得分:1)
要接收JSON,您需要使用ImageDTO
@RequestBody
参数
@RequestMapping(value = { "/upload_image" }, method = RequestMethod.POST)
public @ResponseBody void uploadImage(final @RequestBody ImageDTO image)
答案 1 :(得分:1)
遇到了类似的情况,这就是我想出的。两者都不是那么干净的方式,但工作完美。您需要从客户端发送多部分请求:
注意:保存文件的变量的数据类型为InputStream
。您需要相应地更改
如果您不了解自己的文件数,这将非常有用 正在收到您的请求。
// imports
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
// code flow
// HttpServletRequest request
final FileItemFactory factory = new DiskFileItemFactory();
final ServletFileUpload fileUpload = new ServletFileUpload(factory);
List items = null;
private Map<String, InputStream> fileMap = new HashMap<String, InputStream>();
if (ServletFileUpload.isMultipartContent(request)) {
// get the request content and iterate through
items = fileUpload.parseRequest(request);
if (items != null) {
final Iterator iter = items.iterator();
while (iter.hasNext()) {
final FileItem item = (FileItem) iter.next();
final String fieldName = item.getFieldName();
final String fieldValue = item.getString();
// this is for non-file fields
if (item.isFormField()) {
switch (fieldName) {
case "imageId" :
// set inside your DTO field
break;
// do it for other fields
}
} else {
// set the image in DTO field
}
}
}
}
在这种情况下,您必须处理固定数量的表单 领域。我在ReST方法中实现如下:
@Path("/upload")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public ResponseDTO upload(FormDataMultiPart multiPartData) {
// non-file fields
final String imageId = multiPartData.getField("imageId").getValue();
// for file field
final FormDataBodyPart imagePart = multiPartData.getField("image");
final ContentDisposition imageDetails= imagePart.getContentDisposition();
final InputStream imageDoc = imagePart.getValueAs(InputStream.class);
// set the retrieved content in DTO
}
答案 2 :(得分:0)
我有相同的结果 - 在我介绍@ModelAttribute注释之前,所有DTO成员都是NULL。现在一切正常,这是工作代码:
控制器方法:
@RequestMapping(value = "/save", method = RequestMethod.POST,
consumes = { "multipart/form-data" })
public void create(@Valid @ModelAttribute("entryForm") final EntryDTO entryDTO,
final BindingResult validationResult) throws FormValidationError {
validate(entryDTO, validationResult);
entryService.save(entryDTO);
}
<强> DTO 强>:
public class EntryDTO {
private String phrase;
private String translation;
private MultipartFile imageFile;
}
<强>表格强>:
<form method="post" name="entryForm" action="http://localhost:8080/save"
enctype="multipart/form-data">
<p><input type="text" name="phrase" value="test"/> phrase</p>
<p><input type="text" name="translation" value="тест"/> translation</p>
<p><input type="file" name="imageFile"/></p>
<p><input type="submit"/></p>
</form>
注意,表单名为“entryForm”,相应地名为@ModelAttribute(“entryForm”)。