我正在尝试实现一个使用excel文件的rest api。我正在使用spring-boot,代码可用here。
使用 FileSystemResource 进行有效负载时,代码运行正常。但我无法使用ByteArrayResource代替 FileSystemResource :
RestApi.java:
static final String BODY = "Message : "+ message
+"\r\n"+"Contact : "+Name
+"\r\n"+"Contact Phone : "+Mobile
+"\r\n"+"Contact Email : "+Email
+"\r\n"+"Home Location : "+Address
+"\r\n\n"+VPROVIDOR ;
RestApiTest:
@RestController
public class RestApi {
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@PostMapping("/api/upload")
public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile uploadfile) {
LOGGER.debug("Single file upload!");
try {
LOGGER.info("\n\n ****** File name: {}, type {}! ************", uploadfile.getOriginalFilename(), uploadfile.getContentType());
this.processExcelFile(uploadfile.getInputStream());
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>("Successfully uploaded - " + uploadfile.getOriginalFilename(), new HttpHeaders(), HttpStatus.OK);
}
private List<String> processExcelFile(InputStream stream) throws Exception {
List<String> result = new ArrayList<String>();
//Create Workbook instance holding reference to .xlsx file
try(XSSFWorkbook workbook = new XSSFWorkbook(stream);) {
//Get first/desired sheet from the workbook
XSSFSheet sheet = workbook.getSheetAt(0);
//Iterate through each rows one by one
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
String cellValue = row.getCell(0).getRichStringCellValue().toString();
result.add(cellValue);
LOGGER.info("\n\n ****** Cell value: {} ************", cellValue);
}
return result;
}
}
}
运行测试时出现以下错误:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class RestApiTest {
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private ResourceLoader loader;
@Test
public void testUploadFile() throws Exception {
Resource resource = this.loader.getResource("classpath:test.xlsx");
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
// parts.add("file", new FileSystemResource(resource.getFile()));
parts.add("file", new ByteArrayResource(IOUtils.toByteArray(resource.getInputStream())));
String response = this.restTemplate.postForObject("/api/upload", parts, String.class);
Assertions.assertThat(response).containsIgnoringCase("success");
}
}
有什么想法吗?
答案 0 :(得分:6)
使用loader.getResource(...)时,您必须使用资源本身,如上所述。所以你不需要ByteArrayResource。我遇到了这个问题,但我没有使用classpath中的资源。因此,如果有人真的需要使用ByteArrayResource,这是我的解决方法
public class FileNameAwareByteArrayResource extends ByteArrayResource {
private String fileName;
public FileNameAwareByteArrayResource(String fileName, byte[] byteArray, String description) {
super(byteArray, description);
this.fileName = fileName;
}
@Override
public String getFilename() {
return fileName;
}
}
然后使用它
parts.add("file", new FileNameAwareByteArrayResource("filename", byteArray));