如何将JavaScript生成的.wav格式BLOB发送至Java Servlet程序
解决浏览器录制音频Blob传输到Java Servlet的问题
我之前也碰到过类似的坑——直接用URL对象传Blob很容易因为请求格式不对导致Servlet接收失败,换成FormData+标准文件上传流程就靠谱多了,下面给你一步步拆解实现:
一、前端JavaScript发送Blob
核心是把WAV Blob包装进FormData对象里,这是浏览器传输文件的标准方式,Servlet那边也能很好地解析。
示例代码:
// 假设你已经通过MediaRecorder拿到了录制好的wavBlob const wavBlob = new Blob(recordedChunks, { type: 'audio/wav' }); // 创建FormData并添加音频文件 const formData = new FormData(); // 这里的"audioFile"是参数名,后端要对应这个名字 formData.append('audioFile', wavBlob, 'recorded_audio.wav'); // 用Fetch API发送请求(也可以用XMLHttpRequest) fetch('/your-servlet-path', { method: 'POST', body: formData }) .then(response => response.text()) .then(result => { console.log('上传成功,后端返回:', result); }) .catch(error => { console.error('上传失败:', error); });
关键注意点:
- 不要手动设置
Content-Type为multipart/form-data——Fetch会自动根据FormData生成正确的请求头(包括boundary分隔符),手动设置反而会因为缺少boundary导致后端解析失败。 append方法的第三个参数是文件名,可选,但建议加上,方便后端识别文件类型。
二、Java Servlet接收音频文件
Servlet需要开启对multipart/form-data请求的支持,然后通过Part对象获取上传的文件。
示例代码:
import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import java.io.IOException; import java.io.InputStream; // 必须添加@MultipartConfig注解,开启文件上传支持 @WebServlet("/your-servlet-path") @MultipartConfig( fileSizeThreshold = 1024 * 1024, // 1MB,超过这个大小的文件会写到磁盘临时文件 maxFileSize = 1024 * 1024 * 5, // 单个文件最大5MB maxRequestSize = 1024 * 1024 * 10 // 整个请求最大10MB ) public class AudioUploadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取前端传过来的音频文件,参数名要和前端append的"audioFile"一致 Part audioPart = request.getPart("audioFile"); if (audioPart == null) { response.getWriter().write("未接收到音频文件"); return; } // 获取文件名(可选) String fileName = getFileName(audioPart); System.out.println("接收的文件名:" + fileName); // 获取音频文件的输入流,用于后续处理(比如保存到磁盘、转码等) InputStream audioInputStream = audioPart.getInputStream(); // 这里写你的音频处理逻辑,比如读取流、解析WAV数据等 // ... response.getWriter().write("音频文件接收成功"); } // 辅助方法:从Part中提取文件名 private String getFileName(Part part) { String contentDisposition = part.getHeader("content-disposition"); for (String token : contentDisposition.split(";")) { if (token.trim().startsWith("filename")) { return token.substring(token.indexOf('=') + 1).trim().replace("\"", ""); } } return "unknown_audio.wav"; } }
关键注意点:
- 必须添加
@MultipartConfig注解,否则Servlet无法解析multipart/form-data类型的请求,会导致getPart()返回null。 - 如果你的项目是传统的web.xml配置而不是注解,需要在web.xml中给对应的Servlet添加
<multipart-config>配置块。 - 处理输入流时要注意关闭资源,避免内存泄漏。
常见问题排查
- 后端接收不到文件:检查前端FormData的参数名和后端
getPart()的参数是否完全一致;确认Servlet加了@MultipartConfig。 - 请求报错404:确认Servlet的映射路径和前端fetch的URL一致。
- 文件大小超出限制:调整
@MultipartConfig中的maxFileSize和maxRequestSize参数。
内容的提问来源于stack exchange,提问作者Sumbuble
相关产品推荐
相关产品推荐

