可以同时使用JSON和Multipart Form的REST服务

时间:2015-01-21 08:52:20

标签: java json rest spring-mvc

我需要在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。

是否可以使同一方法处理两种内容类型?

谢谢。

3 个答案:

答案 0 :(得分:1)

要接收JSON,您需要使用ImageDTO

标记@RequestBody参数
@RequestMapping(value = { "/upload_image" }, method = RequestMethod.POST)
public @ResponseBody void uploadImage(final @RequestBody ImageDTO image) 

答案 1 :(得分:1)

遇到了类似的情况,这就是我想出的。两者都不是那么干净的方式,但工作完美。您需要从客户端发送多部分请求

注意:保存文件的变量的数据类型为InputStream。您需要相应地更改

  1. 如果您不了解自己的文件数,这将非常有用 正在收到您的请求。

    // 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
                }
            }
        }
    }
    
  2. 在这种情况下,您必须处理固定数量的表单 领域。我在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”)。