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

@混合多部分请求的RequestPart,Spring MVC 3.2

罗昊空
2023-03-14

我正在开发基于Spring 3.2的RESTful服务。我遇到了一个控制器处理混合多部分HTTP请求的问题,第二部分是XML或JSON格式的数据,第二部分是图像文件

我正在使用@Request estPart注释来接收请求

@RequestMapping(value = "/User/Image", method = RequestMethod.POST,  consumes = {"multipart/mixed"},produces="applcation/json")

public
ResponseEntity<List<Map<String, String>>> createUser(
        @RequestPart("file") MultipartFile file, @RequestPart(required=false) User user) {

    System.out.println("file" + file);

    System.out.println("user " + user);

    System.out.println("received file with original filename: "
            + file.getOriginalFilename());

    // List<MultipartFile> files = uploadForm.getFiles();
    List<Map<String, String>> response = new ArrayList<Map<String, String>>();
    Map<String, String> responseMap = new HashMap<String, String>();

    List<String> fileNames = new ArrayList<String>();

    if (null != file) {
        // for (MultipartFile multipartFile : files) {

        String fileName = file.getOriginalFilename();
        fileNames.add(fileName);

        try {
            file.transferTo(new File("C:/" + file.getOriginalFilename()));
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    responseMap.put("displayText", file.getOriginalFilename());
    responseMap.put("fileSize", "" + file.getSize());
    response.add(responseMap);

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.add("Accept", "application/json");
    return new ResponseEntity<List<Map<String, String>>>(response,
            httpHeaders, HttpStatus.OK);

}

User.java会这样-

@XmlRootElement(name = "User")


public class User implements Serializable { 
    private static final long serialVersionUID = 1L;

    private int userId;
    private String name;
    private String email;

    private String company;
    private String gender;

    //getter setter of the data members
}

据我所知,使用@RequestPart注释,我希望根据XML多部分部分的内容类型对其进行评估,并最终将其解编组到我的用户类中(我使用的是Jaxb2,封送拆收器/取消封送拆收器在应用程序上下文中正确配置,当我将XML数据作为主体传递并使用@RequestBody注释时,该过程对于所有其他控制器方法都能正常工作)。

但实际情况是,尽管文件被正确地找到并解析为MultipartFile,但“用户”部分永远看不到,请求总是失败,与控制器方法签名不匹配。

我复制了几个客户端类型的问题,我相信多部分请求的格式是可以的。

请帮助我解决此问题,可能会有一些解决方法来接收混合/多部分请求。

感谢和问候,

拉格文德拉

共有3个答案

程承恩
2023-03-14

您可以使用@Request estPartorg.springframework.web.bind.annotation.Request estPart;它用作组合@Request estBody和文件上传。

使用@Request estParam这样的@Request estParam("file")MultipartFile文件,您可以只上传文件和多个单个数据(键值),例如

    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST,  consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
    public void saveFile(
                         @RequestParam("userid") String userid,
                         @RequestParam("file") MultipartFile file) {

    }

您可以使用@Request estPart等发布JSON对象数据和文件

    @RequestMapping(value = "/patientp", method = RequestMethod.POST,  consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<?> insertPatientInfo(
                                            @RequestPart PatientInfoDTO patientInfoDTO,
                                            @RequestPart("file") MultipartFile file) {
}

您不限于将多部分文件上载直接用作控制器方法参数。表单对象可以包含Part或MultipartFile字段,Spring自动知道它必须从文件部分获取值,并适当地转换值。

上述方法可以响应前面演示的包含单个文件的多部分请求。这是因为Spring有一个内置的HTTP消息转换器来识别文件部分。除了javax.servlet.http.部分类型之外,您还可以将文件上传转换为org.springframework.web.multipart.MultipartFile。如果文件字段允许多个文件上传,如第二个多部分请求所示,只需使用数组或部件集合或MultipartFiles。

        @RequestMapping(value = "/patientp", method = RequestMethod.POST,  consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
    public ResponseEntity<?> insertPatientInfo(
                                                @RequestPart PatientInfoDTO patientInfoDTO,
                                                @RequestPart("files") List<MultipartFile> files) {
    }

很乐意帮助。。。

尹光辉
2023-03-14

不确定您是否解决了问题,但我也遇到了一个类似的问题,在将@RequestPart和MultipartFile混合在一起时,我的控制器没有拾取我的JSON对象。

您的调用的方法签名看起来正确:

public ResponseEntity<List<Map<String, String>>> createUser(
        @RequestPart("file") MultipartFile file, @RequestPart(required=false) User user) {

// ... CODE ... 
}

但是,请确保您的请求如下所示:

POST /createUser
Content-Type: multipart/mixed; boundary=B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E

--B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E
Content-Disposition: form-data; name="user";
Content-Type: application/xml; charset=UTF-8

<user><!-- your user xml --></user>
--B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E
Content-Disposition: form-data; name="file"; filename="A551A700-46D4-470A-86E7-52AD2B445847.dat"
Content-Type: application/octet-stream

/// FILE DATA
--B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E--
邢昊焜
2023-03-14

我设法解决了这个问题

endpoint示例

@PostMapping("/")
public Document create(@RequestPart Document document,
                       @RequestPart(required = false) MultipartFile file) {
    log.debug("#create: document({}), file({})", delegation, file);
    //custom logic
    return document;
}

例外:

"error_message": "Content type 'application/octet-stream' not supported"

从下一个方法抛出异常:

org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(HttpInputMessage,MethodParameter,Type)

解决方案:

我们必须创建自定义转换器@Component,它实现HttpMessageConverter或HttpMessageConverter并了解MediaType。APPLICATION_OCTET_STREAM。对于简单的解决方法,扩展AbstractJackson2HttpMessageConverter就足够了

@Component
public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {

/**
 * Converter for support http request with header Content-Type: multipart/form-data
 */
public MultipartJackson2HttpMessageConverter(ObjectMapper objectMapper) {
    super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
}

@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
    return false;
}

@Override
public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
    return false;
}

@Override
protected boolean canWrite(MediaType mediaType) {
    return false;
}
}
 类似资料:
  • 我需要向我的Spring控制器发送一个带有json的文件。我有以下控制器类: 但当我在服务器上使用以下命令时: 我得到415不支持的媒体类型! 有线索吗?

  • 有一个只接受内容类型multipart/mixed的REST API。 正在尝试使用restTemplate并生成内容类型为multipart/mixed的REST请求。如果注释setContentType restTemplate默认为多部分/表单数据。 但运气不好,举个例子,我如何调用API生成多部分/混合请求? 也许这个有帮助

  • 问题内容: 我有一个API端点,必须向其发送多部分HTTP请求,该请求由两部分组成(文件系统文件)和(JSON对象)。 经过一些研究,我发现了如何在AngularJS中执行多部分请求: 1) 该函数最初具有以下形式: 此实现的结果是,请求的各个部分没有设置。 Blob ,对象看起来像这样(有点混乱,基本上第一部分是of ,第二个): 第二种方法为请求的每个部分设置了正确的内容,但没有为部分设置任何

  • 我正在使用Nodejs连接GoogleApis v35。0.0告诉Google更新或删除Google索引中的页面。当我通过Google索引批处理请求发送请求时,我陷入了多部分/混合请求,多部分的主体。 通过遵循索引API文档,我可以向Google发送一个单独的页面更新请求。但是由于谷歌每天最多有200个请求,所以我需要更新更多的URL。所以,我尝试使用谷歌索引批量请求,它最多可以对100个单独的请

  • 我使用的是ApacheHttpComponentsV4.3.3(maven httpclient和httpmime)。我需要上传一个带有元数据的文件。工作的curl命令如下所示。 curl-k-i-h“content-type:multipart/mixed”-x post--form'field1=val1'--form'field2=val2'--form'file=@somefile.zip

  • 当我尝试上传一个文件和标题时,我得到以下异常。我正在将Content-Type头设置为multipart/form-data。 我如何在Spring Security后面做文件上传?这个请求似乎从未被转换成MultiPartHttpServerRequest,所以它不起作用? 如果更改方法签名以采用@RequestParam MultipartFile,则会出现如下异常: ...但我在XML中配置