Проблема с загрузкой MultipartFile из React / Node - PullRequest
0 голосов
/ 24 мая 2018

У меня есть следующий контроллер JAVA:

    @RequestMapping(value = "/data/upload", method = RequestMethod.POST)
    public
    @ResponseBody
    void uploadData(@RequestParam("file") MultipartFile file) throws IOException {
        logger.info("Received File for Ingestion");
        dataUploadService.processData(file.getInputStream());
    }

Код узла на стороне сервера:

serviceCall(serviceCallRequestData, request, finalResponse) {
        logger.info('Making remote request: ' + JSON.stringify(serviceCallRequestData));

        let file = request.files['file']; // file: Object {name: "sample_aspect_review_upload.csv", encoding: "7bit", mimetype: "text/csv", mv: }
        let formData = new FormData();
        formData.append('file', Buffer.from(file.data));

        fetch(serviceCallRequestData.url, {
            method: serviceCallRequestData.requestObject.method,
            headers: serviceCallRequestData.requestObject.headers,
            body: formData
        }).then(response => {
            if (response.status !== 200) {
                logger.error(`Error while making http call requestData: ${JSON.stringify(serviceCallRequestData)}`);
                finalResponse.status(500).send('Internal server error');
                return;
            }

            return response.json();
        }).then((json) => {
            logger.info(`Returning response for aspect-review-file-upload: ${JSON.stringify(json)}`);
            finalResponse.status(200).send(JSON.stringify(json));
        }).catch((e) => {
            logger.error(`Error while making http call requestData: ${JSON.stringify(serviceCallRequestData)} error: ${JSON.stringify(e)}`);
            finalResponse.status(500).send('Internal server error');
        });
    }

Попытка загрузить CSV-файл, например:

"product_id","review_id","aspect_id","rating","confidence_score","indices"
"pid","rid","aid",1,0.851955,"[{\"s\":0,\"e\":114,\"highlights\":[39,68]}]"

Загрузка происходит легко из POSTMAN.См. Снимок экрана ниже: enter image description here

Получение ошибки в JAVA: Получено Неизвестное исключение org.springframework.web.bind.MissingServletRequestParameterException: Обязательный параметр MultipartFile: «file» не являетсяприсутствует , когда я не передаю заголовок contentType из React.

Получение ошибки в JAVA: org.apache.commons.fileupload.FileUploadException: запрос был отклонен, так как не было найдено многокомпонентной границы когда я передаю заголовок contentType из React как 'Content-Type': 'multipart / form-data'

Тот же код на стороне сервера Node для контроллера JAVA, как:

    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.APPLICATION_JSON)
    public Response uploadFile(
            @FormDataParam("file") InputStream inputStream,
            @FormDataParam("file") FormDataContentDisposition fileDetail
    ) throws IOException {
        logger.debug("Request to upload data file-name: {}", fileDetail.getName());

        dataUploadService.processData(inputStream);
        return Response.ok().build();
    } 

работает правильно.

Что я делаю не так?Пожалуйста, помогите

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Из локона почтальона вы можете увидеть следующую команду:

curl -i -X POST -H "Content-Type:multipart/form-data" -F "file=@\"/pathto/sample.csv\";type=text/csv;filename=\"sample.csv\"" 'http://localhost:8080/data/upload'

Итак, я попытался добавить type=text/csv;filename=\"sample.csv\" в данные формы, так что это должно работать:

    let file = request.files['file'];
    let formData = new FormData();
    formData.append("file", Buffer.from(file.data), {
        filename: file.name,
        contentType: file.mimetype,
    });

    fetch(serviceCallRequestData.url, {
        method: serviceCallRequestData.requestObject.method,
        headers: serviceCallRequestData.requestObject.headers,
        body: formData
    }).then(response => {
        if (response.status !== 200) {}
    });
0 голосов
/ 01 июня 2018

Несколько предположений:

  1. В своем определении конечной точки REST вы указываете файл как параметр запроса, который используется для извлечения параметров из самого URI, в то время как выгрузка из нескольких частей находится в телезапрос POST.

    Добавьте consumes={} и вместо @RequestParam вы можете использовать @RequestBody аннотацию:

    @RequestMapping(value = "/data/upload", method = RequestMethod.POST,
      consumes = {"multipart/mixed", "multipart/form-data"}
    )
    void uploadData(@RequestBody MultipartFile file) //body will be the whole JSON payload
    

    ИЛИ еще лучше использовать @RequestPart, где вы можете назвать элемент:

    @RequestMapping(value = "/data/upload", method = RequestMethod.POST,
      consumes = {"multipart/mixed", "multipart/form-data"}
    )
    void uploadData(@RequestPart (value="file") MultipartFile file) //gets file from JSON
    
  2. Укажите опции для FormData:

    form.append('file', Buffer.from(file.data), {
      filename: 'image1.jpg', // ... OR:
      filepath: 'photos/image1.jpg',
      contentType: 'image/jpeg',
      knownLength: 19803
    });
    
    form.submit('http://example.com/', function(err, res) {
      if (err) throw err;
      console.log('Done');
    });
    

Можете ли вы подтвердить (используя что-то вроде WireShark ), чтоточно отправляется из React?

...