@RequestPart与混合的多部分请求,Spring MVC 3.2 [英] @RequestPart with mixed multipart request, Spring MVC 3.2

查看:306
本文介绍了@RequestPart与混合的多部分请求,Spring MVC 3.2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm developing a RESTful service based on Spring 3.2. I'm facing a problem with a controller handling mixed multipart HTTP request, with a Second part with XMLor JSON formatted data and a second part with a Image file .

我正在使用

I am using @RequestPart annotation for receiving the request

@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将像这样-

User.java will be like this-

@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批注,我希望根据其Content-Type评估XML多部分,最后将其解编入我的User类(我使用的是Jaxb2,编组器/解组器是正确的在我将XML数据作为正文传递并使用@RequestBody注释时,在应用程序上下文中配置该过程,并且该过程对于所有其他控制器方法均能正常工作.

To my understanding, using the @RequestPart annotation I would expect the XML multipart section to be evaluated depending on its Content-Type and finally un-marshalled into my User class (I'm using Jaxb2, the marshaller/unmarhaller is properly configured in the application context and the procedure is working fine for all the other controller methods when I pass the XML data as body and use the @RequestBody annotation).

但是实际上发生的是,尽管正确找到了文件并将其解析为MultipartFile,但从未看到用户"部分,并且请求始终失败,与控制器方法签名不匹配.

But what is actually happening is that, although the file is correctly found and parsed as MultipartFile, the "user" part is never seen and the request is always failing, not matching the controller method signature.

我重现了几种客户端类型的问题,并且我相信多部分请求的格式是可以的.

I reproduced the problem with several clients type and I am confident the format of the multipart request is ok.

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

Please help me to solve this issue, Maybe some workaround will be there to receive mixed/multipart request.

感谢和问候,

拉格芬德拉

推荐答案

我设法解决了问题

端点示例:

@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"

从下一个方法引发异常:

Exception is thrown from the next method:

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

解决方案:

我们必须创建自定义转换器@Component,该转换器实现 HttpMessageConverter HttpMessageConverter ,并且了解 MediaType.APPLICATION_OCTET_STREAM .对于简单的解决方法,只需扩展 AbstractJackson2HttpMessageConverter

We have to create custom converter @Component, which implements HttpMessageConverter or HttpMessageConverter and knows about MediaType.APPLICATION_OCTET_STREAM. For simple workaround it's enough to extend 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;
}
}

这篇关于@RequestPart与混合的多部分请求,Spring MVC 3.2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆