如何使用SpringMVC和MockMVC为文件上载发布multipart/form-data

 承志68694849 发布于 2023-02-12 18:42

我创建了一个使用javax.ws.rs工作得很好的照片上传器.这是它的标志性和基本要点:

@POST
@Path("/upload/photo")
@Consumes("multipart/form-data")
@Produces("application/json")
public String uploadPhoto(InputStream stream){
        try {
            int read = 0;
            FileOutputStream fos = new FileOutputStream(file);
            CountingOutputStream out = new CountingOutputStream(fos);
            byte[] bytes = new byte[MAX_UPLOAD_SIZE];

            while ((read = stream.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }
            out.flush();
            out.close();
        } catch (IOException e) {
            // TODO throw!
            e.printStackTrace();
        }
    //...
}

我可以使用apache.commons.httpClient库测试这个,如下所示:

    @Test
    public void testUpload() {

        int statusCode = 0;
        String methodResult = null;

        String endpoint = SERVICE_HOST + "/upload/photo";

        PostMethod post = new PostMethod(endpoint);

        File file = new File("/home/me/Desktop/someFolder/image.jpg");

        FileRequestEntity entity = new FileRequestEntity(file, "multipart/form-data");

        post.setRequestEntity(entity);

        try {
            httpClient.executeMethod(post);
            methodResult = post.getResponseBodyAsString();
        } catch (HttpException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        statusCode = post.getStatusCode();

        post.releaseConnection();
            //...
    }

这很棒!问题是应用程序的其余部分是使用Spring MVC编写的.当我使用Spring Mock MVC测试框架时,程序就会挂起(显示在这个下面的代码片段中).以下是上传者的SpringMVC代码:

@ResponseBody
@RequestMapping(    produces="application/json",
                    consumes="multipart/form-data",
                    method=RequestMethod.POST,
                    value="/photo")
public String uploadPhoto(@RequestPart("file") MultipartFile multipartFile){

            try {
                int read = 0;
                FileOutputStream fos = new FileOutputStream(file);
                CountingOutputStream out = new CountingOutputStream(fos);
                byte[] bytes = new byte[MAX_UPLOAD_SIZE];

                while ((read = multipartFile.getInputStream().read(bytes)) != -1) {
                    out.write(bytes, 0, read);
                }

                out.flush();
                out.close();

            } catch (IOException e) {
                // TODO throw!
                e.printStackTrace();
            }
            //...
}

以下是我使用Spring Mock MVC实现的测试.我认为问题与使用fileUpload(...)有关.有没有办法测试使用正常的帖子(..),就像我可以用apache?我更喜欢使用InputStream作为参数,并避免使用MultipartFile.

@Test
public void testUpload() throws Exception {

    String endpoint = BASE_URL + "/upload/photo";

    FileInputStream fis = new FileInputStream("/home/me/Desktop/someFolder/image.jpg");
    MockMultipartFile multipartFile = new MockMultipartFile("file", fis);

    mockMvc.perform(fileUpload(endpoint)
            .file(multipartFile)
            .contentType(MediaType.MULTIPART_FORM_DATA))
            .andExpect(status().isOk());

}

理想情况下,我想使用Spring MVC和Spring Mock MVC框架,但我提供的代码只是挂在while语句中.就Spring测试中使用fileUpload方法而言,我正在做的是什么?任何建议表示赞赏.

1 个回答
    1. 要向模拟帖子请求添加内容,请使用内容(bytes [])

      媒体类型参数边界是必要的

    此外,使用java.io中的普通旧InputStream作为upload方法的参数是安全的,并且仍然在请求中使用MockMultipartFile.

    @Test
    public void testUpload() throws Exception {
    
                String endpoint = BASE_URL + "/upload/photo";
    
                FileInputStream fis = new FileInputStream("/home/me/Desktop/someDir/image.jpg");
                MockMultipartFile multipartFile = new MockMultipartFile("file", fis);
    
                HashMap<String, String> contentTypeParams = new HashMap<String, String>();
                contentTypeParams.put("boundary", "265001916915724");
                MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams);
    
                mockMvc.perform(
                        post(endpoint)
                        .content(multipartFile.getBytes())
                        .contentType(mediaType))
                        .andExpect(status().isOk());
    }
    

    2023-02-12 18:44 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有