2016-08-18 5 views
0

Я использую Spring 4, и у меня вообще нет проблем с записью контроллеров RESTful. Существует устаревшее веб-приложение, которое использует java.net.HTTPUrlConnection для многопользовательской загрузки. Есть 3 части данных, которые мы загружаем: 1 - это PDF-файл, и у нас есть байты, тогда две другие части данных - всего 2 строковых поля.Загрузка файла MVC Spring с многостраничными данными и модульным тестом

Прежде всего позвольте мне показать вам контроллер Spring REST принимать данные:

@RequestMapping(value = "/save", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data") 
public @ResponseBody boolean saveData(@RequestPart(value = "field1") String field1, @RequestPart(value = "field2") String field2, @RequestParam(value = "pdfbytes") String pdfbytes) 
{ 
    System.out.println("saveData: field1=" + field1); 
    System.out.println("saveData: field2=" + field2); 
    System.out.println("saveData: pdfbytes=" + pdfbytes); 
    boolean response = true; 

    return response; 
} 

Код в переднем конце, для передачи данных с помощью «java.net.HttpURLConnection» выглядит следующим образом:

String boundary = MultiPartFormOutputStream.createBoundary(); 

URL uploadDocumentUrl = new URL(protocol + "://" + host + UPLOAD_EDITED_DOCUMENT); 

    HttpURLConnection urlConn = (HttpURLConnection) MultiPartFormOutputStream.createConnection(uploadDocumentUrl); 
    urlConn.setRequestProperty("Content-Type", MultiPartFormOutputStream.getContentType(boundary)); 
    urlConn.setRequestProperty("Connection", "Keep-Alive"); 
    urlConn.setRequestProperty("Cache-Control", "no-cache"); 
    urlConn.setRequestProperty("User-Agent", userAgent); 
    urlConn.setRequestMethod("POST"); 

    MultiPartFormOutputStream out = new MultiPartFormOutputStream(urlConn.getOutputStream(), boundary); 

    String pdfbytes= getEncodedDocument(pdf); 

    out.writeField("field1", field1); 
    out.writeField("field2", field2); 
    out.writeField("pdfbytes", pdfbytes); 

    out.close(); 
    int responseCode = urlConn.getResponseCode(); 
    String responseMessage = urlConn.getResponseMessage(); 

«MultiPartFormOutputStream» - это настраиваемый объект, который был создан для отправки данных через HttpUrlConnection, это довольно стандартный код. Я действительно доверяю этому в это время.

Итак, основываясь на том, как мы отправляем данные, мне нужно изменить контроллер, чтобы сделать что-то другое, или это выглядит нормально?

Теперь вот код, который я использую для Test Unit, что контроллер:

@Test 
public void testMockUpload() throws Exception 
{ 
    // Load resource being uploaded 
    byte[] pdfbytes = getByteArrayFromFile(FILENAME); 

    MockMultipartFile firstFile = new MockMultipartFile("field1", "", "text/plain", "field1 data".getBytes()); 
    MockMultipartFile secondFile = new MockMultipartFile("field2", "", "text/plain", "field2 data".getBytes()); 
    MockMultipartFile jsonFile = new MockMultipartFile("pdfbytes", "", "text/plain", pdfbytes); 

    MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.fileUpload(BASE_URL + "/save").file(firstFile).file(secondFile).file(jsonFile) 
    .with(user(USERNAME).roles("role1", "role2")).contentType(MediaType.MULTIPART_FORM_DATA_VALUE); 

    this.mockMvc.perform(requestBuilder).andDo(print()).andExpect(status().isOk()); 
} 

и ошибка, я получаю обратно сейчас, это: org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException

который я изучаю. Если мне нужно внести какие-либо изменения в то, как мне нужно создать свой тест, я очень открыт для этого. В конце концов, я получу все, чтобы синхронизировать между передающим кодом, получающим контроллером и модульным тестом.

Заранее благодарен! Как обычно, если есть какие-либо другие данные или информация, я могу предоставить, пожалуйста, дайте мне знать. Благодаря!

ответ

0

Чтобы загрузить один файл, вы должны указать тип RequestParam как org.springframework.web.multipart.MultipartFile;

@RequestMapping(value = "/save", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data") 
      public @ResponseBody boolean saveData(@RequestParam(value = "file") MultipartFile file) 
      { 
       return response; 
      } 

для нескольких файлов, которые я хотел бы попробовать создать форму Wrapper:

public class UploadForm{ 

    private List<MultipartFile> files; 
} 

Bind этого в контроллере:

@RequestMapping(value = "/save", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data") 
    public @ResponseBody boolean saveData(@ModelAttribute uploadForm) 
    { 
     return response; 
    } 

, а затем использовать поддержку Spring в индексированных полей для связывания к коллекции:

Испытание:

MockMultipartFile firstFile = new MockMultipartFile("files[0]", "", "text/plain", "field1 data".getBytes()); 
    MockMultipartFile secondFile = new MockMultipartFile("files[1]", "", "text/plain", "field2 data".getBytes()); 
    MockMultipartFile jsonFile = new MockMultipartFile("files[2]", "", "text/plain", pdfbytes); 

Клиент:

out.writeField("files[0]", file1Bytes); 
out.writeField("files[1]", file2Bytes); 
...