当前位置: 首页 > 知识库问答 >
问题:

可以使用JSON和多部分表单的REST服务

狄雅珺
2023-03-14

我需要在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。从表单向上加载图像,其中内容类型为多部分表单(所有DTO成员均不为null)2。使用JSON上传图像,仅使用imageUrl。在本例中,请求正文如下所示:

{
    "imageId":"1236",
    "imageUrl":"http://some.image.url",
    "image":null
}

当前的实现很好地处理了多部分请求,但在发送JSON时,ImageDTO对象的所有成员中都包含null。

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

谢谢你。

共有3个答案

缪远航
2023-03-14

在引入@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”)。

阴永逸
2023-03-14

我也遇到过类似的情况,下面是我的想法。这两种方法都不是很干净,但都很完美。您需要从客户端发送多部分请求:

注意:保存文件的变量的数据类型是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
    }
    

  • 魏俊茂
    2023-03-14

    要接收JSON,您需要使用@Request estbody标记ImageDTO参数

    @RequestMapping(value = { "/upload_image" }, method = RequestMethod.POST)
    public @ResponseBody void uploadImage(final @RequestBody ImageDTO image) 
    
     类似资料:
    • 如何使用ajax或XMLHttpRequest从javascript调用RESTAPI,以使用内容类型:multipart/form data上载文件。 文件内容是二进制格式的,但我调用的API具有以下请求格式:Authorization:Bearer 我使用以下代码段上传文件内容: 其中formData是二进制格式的文件内容。请建议这是正确的方法还是应该以不同的方式处理。我使用的文件类型是IFC

    • 位卡在这个上,需要上传图像和json一起使用多部分形式...不知道如何发送内容类型标头或上传图像...认为我需要转换为blob...目前我只是发送我从文件输入字段中获得的数据。 任何建议都很好谢谢

    • 我想写一个REST服务,它用一个zipFile和一些json数据来响应,所有的东西都在一个多部分/混合请求中。 现在我尝试使用多部分/混合响应并返回一个MultiValueMap MyMultiValueMap存在以防止类型擦除(泛型)。 这给出了

    • 我正在尝试通过使用多部分数据主体的JMeter构建HTTP请求。 我有一个HTTP头管理器,其内容类型设置为多部分/表单数据;边界=AaB03x。我选择了“将多部分/表单数据用于POST”。 然后我创建了一个数据主体, 当我运行这个程序时,我发现请求没有正确地发送正文,而是发送了一些随机数据, 发布数据: 并给出错误响应, 我的第二个问题是:请求的第3部分发送一个要上载的文件。我可以通过某种方式传

    • 以及multipartConfigElement 但是当我向REST服务发送多部分消息时,仍然会出现以下异常: servlet[dispatcherServlet]在路径[/dev]的上下文中的servlet.service()引发异常[请求处理失败;嵌套异常是java.lang.IllegalArgumentException:预期的multiparthttpServletRequest:是否配