How to use spring's MockMultipartHttpServletRequest? Getting “no multipart boundary was found”

前端 未结 5 424
名媛妹妹
名媛妹妹 2021-01-02 10:53

Clearly I\'m not using this test fixture right. My servlet works just fine in tomcat, but when I try to use this mock, the multi-part boundary is not found. \"the request

相关标签:
5条回答
  • 2021-01-02 11:24

    You need to set the boundary.

    Here there is a good explanations about what is the boundary https://stackoverflow.com/a/10932533/2762092

    To solve your problem try this code.

        import java.io.IOException;
        import java.nio.file.Files;
        import java.nio.file.Path;
        import java.nio.file.Paths;
    
        import org.apache.commons.lang.ArrayUtils;
        import org.springframework.mock.web.MockHttpServletResponse;
        import org.springframework.mock.web.MockMultipartFile;
        import org.springframework.mock.web.MockMultipartHttpServletRequest;
    
    
    public class FileUploadTest {
    
        public void testDoPost() throws IOException {
                Path path = Paths.get("c:\\temp\\test.zip");
                byte[] data = Files.readAllBytes(path);
                MockMultipartFile file = new MockMultipartFile("test.zip", "test.zip",
                        "application/zip", data);
                MockMultipartHttpServletRequest mockRequest = new MockMultipartHttpServletRequest();
                String boundary = "q1w2e3r4t5y6u7i8o9";
                mockRequest.setContentType("multipart/form-data; boundary="+boundary);
                mockRequest.setContent(createFileContent(data,boundary,"application/zip","test.zip"));
                mockRequest.addFile(file);
                mockRequest.setMethod("POST");
                mockRequest.setParameter("variant", "php");
                mockRequest.setParameter("os", "mac");
                mockRequest.setParameter("version", "3.4");
                MockHttpServletResponse response = new MockHttpServletResponse();
                new FileUpload().doPost(mockRequest, response);
            }
    
            public byte[] createFileContent(byte[] data, String boundary, String contentType, String fileName){
                String start = "--" + boundary + "\r\n Content-Disposition: form-data; name=\"file\"; filename=\""+fileName+"\"\r\n"
                         + "Content-type: "+contentType+"\r\n\r\n";;
    
                String end = "\r\n--" + boundary + "--"; // correction suggested @butfly 
                return ArrayUtils.addAll(start.getBytes(),ArrayUtils.addAll(data,end.getBytes()));
            }
    }
    
    0 讨论(0)
  • 2021-01-02 11:26

    Able to add multiple fields ,

       private byte[] createFileContents(String requestId, String date, String image, String invoiceNumber,String imageFile) {
    
        String requestIdField = "--" + BOUNDARY + "\r\n Content-Disposition: form-data; name=\"" + REQUEST_ID_KEY
                + "\";" + "Content-type: " + CONTENT_TYPE + "\r\n value=\"12345\"" + "\r\n\r\n";
        String requestIdValue = requestId + "\r\n";
        String numberFiledField = "--" + BOUNDARY + "\r\n Content-Disposition: form-data; name=\"" + NUMBER_KEY + "\";"
                + "Content-type: " + CONTENT_TYPE + "\r\n value=\"12345\"" + "\r\n\r\n";
        String invoiceValue = invoiceNumber + "\r\n";
        String dateField = "--" + BOUNDARY + "\r\n Content-Disposition: form-data; name=\"" + DATE_KEY + "\";"
                + "Content-type: " + CONTENT_TYPE + "\r\n value=\"12345\"" + "\r\n\r\n";
        String dateValue = date + "\r\n";
        String imageField = "--" + BOUNDARY + "\r\n Content-Disposition: form-data; name=\"" + IMAGE_KEY
                + "\"; filename=\"" + imageFile + "\"\r\n" + "Content-type: " + CONTENT_TYPE + "\r\n\r\n";
        String imageValue = image + "\r\n";
        String end = "\r\n--" + BOUNDARY + "--";
        return ArrayUtils.addAll((requestIdField + requestIdValue + numberFiledField + invoiceValue + dateField
                + dateValue + imageField + imageValue).getBytes(), ArrayUtils.addAll(data, end.getBytes()));
    }
    
    0 讨论(0)
  • 2021-01-02 11:33

    Vote up for Samuel. Though spent one day trying to make it working. The problem was in:

    String end = "--" + boundary + "--";
    

    Should be:

    String end = "\r\n--" + boundary + "--";
    
    0 讨论(0)
  • 2021-01-02 11:34

    My way to test multipart/form-data via mock MVC sending params and files is the following:

        @Test
    void testSendFeedback() throws Exception {
        var builder = MockMvcRequestBuilders.multipart(URL_PATH);
    
        Path path = Files.createTempFile("test-file", "tmp");
        builder = builder.part(new MockPart("image", path.toFile().getName(), Files.readAllBytes(path)));
    
        builder.param("field1", "value1")
            .param("fields2", "value2");
    
        mockMvc.perform(builder.header(HttpHeaders.AUTHORIZATION, YOUR_AUTH_VALUE).contentType(MediaType.MULTIPART_FORM_DATA_VALUE))
            .andDo(print())
            .andExpect(status().isNoContent());
    }
    
    0 讨论(0)
  • 2021-01-02 11:37

    Great answer for Samuel, but a bug:

            String end = "\r\n"+ boundary + "--";
    

    should be:

            String end = "--"+ boundary + "--";
    

    Thanks for his work very much.

    0 讨论(0)
提交回复
热议问题