如何通过Java InputStream将JS录制的BLOB音频存入数据库
Alright, let's walk through this step by step. That blob URL you have is just a browser-internal reference—it doesn't hold the actual binary data, so we need to first extract the real audio blob from it on the frontend, then send that binary data to your Java backend. Once there, we'll use an InputStream to persist it to your database.
Step 1: Frontend (JavaScript) – Extract Blob from Blob URL and Send to Backend
First, we need to fetch the actual Blob object using the blob URL, then send it to your Java API. We'll use fetch for this, and wrap the blob in FormData to handle file uploads properly.
// Your existing blob URL const blobUrl = 'blob:http://127.0.0.1:8888/363f3a17-81d0-4f4d-915c-8d01d288b8bc'; // 1. Fetch the blob from the internal URL fetch(blobUrl) .then(response => response.blob()) .then(audioBlob => { // 2. Package the blob into FormData for upload const formData = new FormData(); // Append the blob, with an optional filename (adjust the extension to match your recording format) formData.append('audioFile', audioBlob, 'recording.wav'); // 3. Send to your Java backend endpoint return fetch('/api/audio/save', { method: 'POST', body: formData }); }) .then(apiResponse => apiResponse.json()) .then(result => console.log('Success:', result)) .catch(error => console.error('Error:', error));
Step 2: Backend (Java) – Receive Data via InputStream and Store in Database
We'll cover two common scenarios: raw Servlet and Spring Boot (since Spring is widely used for Java backends).
Option 1: Raw Java Servlet
If you're using a plain Servlet-based backend, here's how to handle the multipart request, get the InputStream, and save to the database with JDBC:
@WebServlet("/api/audio/save") @MultipartConfig // Required to handle multipart/form-data requests public class AudioSaveServlet extends HttpServlet { // Database configuration (use environment variables or a config file in production!) private static final String DB_URL = "jdbc:mysql://localhost:3306/your_database"; private static final String DB_USER = "your_username"; private static final String DB_PASSWORD = "your_password"; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Get the audio part from the multipart request Part audioPart = request.getPart("audioFile"); try ( // Get InputStream from the uploaded file part InputStream audioStream = audioPart.getInputStream(); // Establish database connection Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD) ) { // SQL query to insert audio data into BLOB column String insertSql = "INSERT INTO audio_records (audio_data, file_name, content_type) VALUES (?, ?, ?)"; try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) { // Set the InputStream directly into the BLOB parameter pstmt.setBinaryStream(1, audioStream, audioPart.getSize()); pstmt.setString(2, audioPart.getSubmittedFileName()); pstmt.setString(3, audioPart.getContentType()); int rowsInserted = pstmt.executeUpdate(); response.setStatus(HttpServletResponse.SC_OK); response.getWriter().write("{\"message\": \"Audio saved successfully\", \"rows_inserted\": " + rowsInserted + "}"); } } catch (SQLException e) { e.printStackTrace(); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); response.getWriter().write("{\"error\": \"Failed to save audio to database\"}"); } } }
Option 2: Spring Boot Controller
If you're using Spring Boot, the code is more concise thanks to Spring's built-in multipart handling and JdbcTemplate:
@RestController @RequestMapping("/api/audio") public class AudioController { @Autowired private JdbcTemplate jdbcTemplate; @PostMapping("/save") public ResponseEntity<Map<String, Object>> saveAudio(@RequestParam("audioFile") MultipartFile audioFile) { try (InputStream audioStream = audioFile.getInputStream()) { String insertSql = "INSERT INTO audio_records (audio_data, file_name, content_type) VALUES (?, ?, ?)"; int rowsInserted = jdbcTemplate.update(insertSql, (PreparedStatement ps) -> { ps.setBinaryStream(1, audioStream, audioFile.getSize()); ps.setString(2, audioFile.getOriginalFilename()); ps.setString(3, audioFile.getContentType()); }); return ResponseEntity.ok(Map.of( "message", "Audio saved successfully", "rows_inserted", rowsInserted )); } catch (IOException | SQLException e) { e.printStackTrace(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(Map.of("error", "Failed to save audio to database")); } } }
Step 3: Database Table Setup
Make sure you have a table with a BLOB column to store the audio data. Here's a MySQL example:
CREATE TABLE audio_records ( id INT AUTO_INCREMENT PRIMARY KEY, audio_data BLOB NOT NULL, -- Stores the binary audio data file_name VARCHAR(255), -- Optional: store the original filename content_type VARCHAR(100), -- Optional: store the audio MIME type (e.g., audio/wav) created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
Key Notes
- Multipart Configuration: For raw Servlets, don't forget the
@MultipartConfigannotation. For Spring Boot, multipart handling is enabled by default, but you can adjust file size limits inapplication.properties:spring.servlet.multipart.max-file-size=100MB spring.servlet.multipart.max-request-size=100MB - Blob URL Validity: Blob URLs are only valid for the current browser session—make sure to send the data before the page refreshes or closes.
- Large Files: If you're dealing with very large audio files, consider implementing chunked uploads to avoid timeouts or memory issues.
内容的提问来源于stack exchange,提问作者Alex Wan Chee Hui

