I want to create a REST API to place Files using Spring-Boot. Together with the file I need to get some Metadata which I would like to get as JSON class. At fist I created a class for the metadata:
@Getter
@Setter
@ToString
@RequiredArgsConstructor
@Entity
@Table(name = FileData.TABLE_NAME)
public class FileData {
public static final String TABLE_NAME = "file_data";
private static final long serialVersionUID = 1342709296259278462L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@GenericGenerator(name = "native", strategy = "native")
@Column(updatable = false)
private Long id;
@Column(updatable = false)
private String userId;
@Column(updatable = false, nullable = false)
private String filename;
private String description;
}
Then I created an API:
@RequestMapping("/files")
public interface FileApi {
@Operation(summary = "Add a new File and return its id.", tags = {"File Upload"})
@PostMapping(path = "/upload",
consumes = {MediaType.MULTIPART_FORM_DATA})
ResponseEntity<String> addFile(@RequestPart(value = "file") final MultipartFile file, @RequestBody FileData fileData, @Context final HttpServletRequest request);
}
I also implemented the method in my Controller. Now I am failing to implement a test for this method. I did following:
@Test
public void uploadFile_success() throws Exception {
final MockMultipartFile file = new MockMultipartFile("file", "test.zip", "text/plain", "test".getBytes());
FileData fileData = new FileData();
fileData.setFilename("bla.zip");
fileData.setDescription("A very nice File");
String address = "/files/upload";
mockMvc.perform(MockMvcRequestBuilders.multipart(address)
.file(file)
.content(MAPPER.writeValueAsString(fileData))
.contentType(MediaType.MULTIPART_FORM_DATA))
.andExpect(status().isOK())
.andExpect(content().string("OK"))
.andReturn();
}
When I run the test, I get HTTP error code 415 and the following error message:
Content type 'multipart/form-data' not supported
Regarding Swagger UI the Request Body shall have multipart/fomr-data. I also removed the contentType call (with same result) and changed it to "application/json" (same result, but with this content type).
Can andybody tell me what content type I have to set?
I could run the test with contentType "application/json" by removing the consumes entry in PostMapping, but in Swagger UI I have then to place the data of the file in a string field in JSON data and cannot transfer a binary file. I think this is not the right way to do it...