You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不转为Base64字符串的情况下将JavaScript Blob上传至JSF?

不转Base64,通过JSF组件上传Blob音频文件

这里提供两种实用方案,分别对应PrimeFaces的<p:remoteCommand>和原生JSF的<h:commandScript>,全程无需将Blob转换为Base64字符串:

方案一:使用PrimeFaces <p:remoteCommand>

1. 后端ManagedBean实现

创建支持文件上传的Bean,用于接收并处理音频文件:

import org.primefaces.model.file.UploadedFile;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

@Named
@ViewScoped
public class AudioUploadBean {
    private UploadedFile audioFile;

    public void uploadAudio() {
        if (audioFile == null) return;
        
        try {
            // 替换为你的实际保存路径
            Files.write(Paths.get("/opt/audio/" + audioFile.getFileName()), audioFile.getContent());
        } catch (IOException e) {
            e.printStackTrace();
            // 可在此添加Faces消息提示错误
            // FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("上传失败:" + e.getMessage()));
        }
    }

    // Getter & Setter
    public UploadedFile getAudioFile() { return audioFile; }
    public void setAudioFile(UploadedFile audioFile) { this.audioFile = audioFile; }
}

2. 前端页面配置

在xhtml页面中定义remoteCommand,并编写JS上传逻辑:

<!-- 绑定Bean的uploadAudio方法 -->
<p:remoteCommand name="uploadAudioCmd" action="#{audioUploadBean.uploadAudio}" 
                 process="@this" ajax="true" />

<script>
// 假设recordedBlob是你录制好的音频Blob对象
function uploadAudioBlob() {
    const formData = new FormData();
    // 参数名必须和Bean中的audioFile属性完全一致
    formData.append('audioFile', recordedBlob, 'my-recorded-audio.wav');

    // 调用remoteCommand,传入FormData并禁用自动处理数据和内容类型
    uploadAudioCmd({
        form: formData,
        contentType: false,
        processData: false
    });
}
</script>

方案二:使用原生JSF <h:commandScript>

1. 后端Bean

可直接复用方案一中的AudioUploadBean,无需额外修改。

2. 前端页面配置

通过commandScript获取请求URL,用XMLHttpRequest发送FormData:

<!-- 绑定Bean的uploadAudio方法 -->
<h:commandScript name="uploadAudioScript" action="#{audioUploadBean.uploadAudio}" 
                 render="@none" />

<script>
function uploadAudioBlob(recordedBlob) {
    const formData = new FormData();
    formData.append('audioFile', recordedBlob, 'my-recorded-audio.wav');

    const xhr = new XMLHttpRequest();
    // 获取commandScript生成的请求地址
    const requestUrl = uploadAudioScript.action;

    xhr.open('POST', requestUrl, true);
    // 不要手动设置Content-Type,浏览器会自动添加正确的multipart边界
    xhr.send(formData);

    // 处理上传结果
    xhr.onload = function() {
        if (xhr.status === 200) {
            console.log('音频上传成功');
        } else {
            console.error('音频上传失败,状态码:' + xhr.status);
        }
    };
}
</script>

关键注意事项

  • 确保项目已配置文件上传支持:PrimeFaces需在web.xml中添加org.primefaces.webapp.filter.FileUploadFilter;原生JSF需依赖javax.servlet.annotation.MultipartConfig或容器的文件上传配置
  • FormData中append的参数名必须和ManagedBean的属性名严格匹配,否则无法完成参数绑定
  • 禁止手动设置Content-Type: multipart/form-data,浏览器会自动处理边界参数,手动设置会导致上传失败
  • Bean需使用@ViewScoped或更宽的作用域,避免请求时Bean被重新实例化导致属性丢失

内容的提问来源于stack exchange,提问作者Bashar Issa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 11:30:22