ByteArrayResource的Spring-boot MultipartFile问题

时间:2017-02-23 12:39:10

标签: spring rest spring-boot multipartform-data

我正在尝试实现一个使用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");
    }
}

有什么想法吗?

1 个答案:

答案 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));