spring - @RequestPart 与混合多部分请求,Spring MVC 3.2

标签 spring rest multipartform-data

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

我正在使用 @RequestPart annotation 用于接收请求

@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 多部分部分根据其 Content-Type 进行评估,并最终取消编码到我的用户类中(我使用的是 Jaxb2,编码器/解码器是正确的在应用程序上下文中配置,并且当我将 XML 数据作为正文传递并使用 @RequestBody 注释时,该过程对于所有其他 Controller 方法都可以正常工作)。

但实际发生的是,虽然文件被正确找到并解析为 MultipartFile,但“用户”部分从未见过,请求总是失败,与 Controller 方法签名不匹配。

我用几种客户端类型重现了这个问题,我相信多部分请求的格式是可以的。

请帮我解决这个问题,也许会有一些解决方法来接收混合/多部分请求。

感谢和问候,

拉格文德拉

最佳答案

我已经解决了这个问题

端点示例:

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

异常(exception):

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

从下一个方法抛出异常:

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

解决方案:

我们必须创建自定义转换器@Component,它实现了 HttpMessageConverterHttpMessageConverter 并了解 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 - @RequestPart 与混合多部分请求,Spring MVC 3.2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16230291/

相关文章:

java - JSON VS 简单的字符串操作来解析 Android 中的 HttpRequest

python - DRF 关联模型中的单个字段

java - 通过多部分表单数据上传时如何知道文件大小?

java - 当我需要使用两列时如何使用@oneToMany

java - Web 应用实用程序类

java - Jersey:返回字符串列表

spring - 如何启用 Spring Reactive Web MVC 来处理多部分文件?

android - Android 上的 Kotlin 多部分请求

spring - TCP 客户端 Spring 与 Java 配置的集成

java - Hibernate Criteria 集合的最新日期字段