【问题标题】:Sending Blob data from Angular6 client to Spring Boot API as MultipartFile将 Blob 数据作为 MultipartFile 从 Angular6 客户端发送到 Spring Boot API
【发布时间】:2019-03-05 17:40:43
【问题描述】:

我正在尝试将音频作为 MultiPart 文件上传到 Spring Boot API。我从来没有在 Angular2.x 应用程序中做过类似的事情,所以完全不确定我的方法是否正确。我不断从 api 收到 500 错误,并认为可能是我的音频数据没有以正确的格式发送......我在这里遗漏了什么吗?我查看了与使用 javaFX 在该 gui 中使用 javaFX 完成的相同 API 的 gui 代码,音频被记录,保存为 wav,然后发送到 api 端点。我应该先保存录音的 .wav 文件,然后将其读取/发送到 API,还是可以像现在一样使用 Blob?

我的代码:

the Kotlin/spring boot endpoint:@PostMapping("/vb/Verify")
    fun verify(@RequestParam("Audio") file:MultipartFile,
               @RequestParam(name = "SessionID") sessionId: String,
               @RequestParam(name = "Risk") risk: String,
               @RequestParam(name = "Strategy") strategy:String,
               @RequestParam(name = "AudioType") audioType:String,
               @RequestParam(name = "Channel") channel:String):VerifyResponseDTO {

        val audioBytes = StreamUtils.copyToByteArray(file.inputStream)
        return vbService.verify(sessionId, audioBytes, audioType, strategy, channel, Risk.byCode(risk))

    }


my angular component code:


constructor(private restService: RestService) {
    const onSuccess = stream => {
      this.mediaRecorder = new MediaRecorder(stream);
      this.mediaRecorder.onstop = e => {
        const audio = new Audio();
        const blob = new Blob(this.chunks, {type : 'audio/wav'});
        this.chunks.length = 0;
        audio.src = window.URL.createObjectURL(blob);                
        this.verify(blob);
        audio.load();
        audio.play();
      };

      this.mediaRecorder.ondataavailable = e => this.chunks.push(e.data);
    };

    navigator.getUserMedia = (navigator.getUserMedia ||
      navigator.webkitGetUserMedia ||
      navigator.mozGetUserMedia ||
      navigator.msGetUserMedia);

    navigator.getUserMedia({ audio: true }, onSuccess, e => console.log(e));
  }

verify(blob: Blob) {
    this.restService.startSession()
    .subscribe((res) => {
      console.log(res);
      this.restService.verify(blob)
      .subscribe((res) => {
        console.log(res);
      }, (err) => {
        console.log(err);
      });
    }, (err) => {
      console.log(err);
    });
  }



my Angular Service verify function:
verify(blob: Blob): Observable<any> {     
    let formData:FormData = new FormData();
    formData.append("SessionID", "neld02");
    formData.append("Strategy", "Phrase");
    formData.append("AudioType", "Header");
    formData.append("Risk", "Lo")
    formData.append("Channel", "Smart")
    formData.append('Audio', blob);   
    formData.append("Text", "");


    return this.hc.post(`${this.api}/Verify`, formData);
   }

【问题讨论】:

  • 您是否检查了后端的日志以了解为什么它正在返回 500?你能看到它抛出了什么错误吗?
  • 我没有,我只是不确定我在前端的方法......

标签: javascript angular typescript spring-boot kotlin


【解决方案1】:

使用@RequestPart 表示文件,另一个@RequestPart 封装元数据音频属性:

@PostMapping("/vb/Verify")
fun verify(@RequestPart(value = "audio") file:MultipartFile,
           @RequestPart(value = "audioMetadata") properties: AudioMetadata,

在角度方面使用相同的方法:

uploadFileCreateTable(payload) {

const formData = new FormData();
formData.append('audio', payload.file);

const audioMetadata = {
  sessionId: payload.sessionId,
  strategy: payload.strategy
  ... //and so on
};
formData.append('audioMetadata', new Blob([ JSON.stringify(audioMetadata) ], {
  type: 'application/json'
}));

return this.http.post(`${this.api}/Verify`, formData);
};

【讨论】:

    【解决方案2】:

    我建议从客户端为您的音频 blob 发送 base64 字符串(因此使用任何 angular module 将您的 blob 转换为 base 64 字符串)然后在您的后端您可以像这样处理 base64 字符串。

        Decoder decoder = Base64.getDecoder();
        byte[] decodedByte = decoder.decode(base64Audio.split(",")[1]);
        FileOutputStream fos = new FileOutputStream("your audio file name");
        fos.write(decodedByte);
        fos.close();
    

    【讨论】:

      【解决方案3】:

      指的是@RequestParam("Audio") file:MultipartFile

      我有类似的问题,你能尝试将 blob 映射到 file() 对象吗?

        const file = new File([blob], 'audio.wav');
        const formData = new FormData();
        formData.append('File', file, file.name); // file.name was mandatory for us (otherwise again an error occured)
      

      【讨论】:

      • 不,没有这样做,似乎音频仍然不是 wav 格式,我从细微差别语音验证中收到以下错误:2018-10-10 09:30:38.927 DEBUG 31396 --- [nio-8110-exec-2] c.xib.vodacom.ans.service.NuanceService : Nuance 验证响应 Nuance.VB.BadAudioFormatException: 不是 Wav 文件
      • 您能否在您的呼叫请求中检查 Chrome 开发人员工具请求您的 表单数据,然后单击查看源并检查您的内容类型是什么。它应该如下所示: Content-Disposition: form-data;名称="文件"; filename="image.jpeg" Content-Type: application/octet-stream
      猜你喜欢
      • 2020-06-27
      • 2021-02-09
      • 2019-06-24
      • 1970-01-01
      • 2015-04-06
      • 2019-04-17
      • 2018-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多