Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Building a Java-Based Music Streaming Platform with Spring Boot and Vue.js

Tech 1

Architectural Foundation and Technology Stack

The backend infrastructure relies on Spring Boot, an opinionated framework that accelerates the development of production-ready Java applications. By embracing convention over configuration, it eliminates verbose XML setups and manual bean wiring. The framework automatical configures components based on classpath dependencies, allowing engineers to concentrate on domain logic rather than infrastructure boilerplate. Build automation is handled through Maven or Gradle, which resolve transitive dependencies and integrate seamlessly with project scaffolding tools for rapid initialization.

The frontend layer is constructed with Vue.js, a progressive JavaScript framework engineered for approachability and performance. Its core reactivity system establishes a transparent dependency-tracking mechanism, ensuring the DOM updates efficiently whenever the underlying state mutates. Directives like v-model facilitate seamless two-way data binding, while a well-defined component lifecycle provides precise hooks for initialization, mounting, updating, and teardown operations. This architecture decouples the user interface from business logic, enabling modular development and straightforward maintenance.

System Feasibility and Requirement Analysis

Evaluating project viability requires a multi-dimensional assessment covering technical, economic, and operational factors.

  • Technical Viability: The Java ecosystem offers robust concurrency handling, extensive multimedia processing libraries, and mature ORM solutions. Coupled with Spring Boot's ecosystem and Vue's reactive paradigm, the stack provides a stable foundation for handling audio streaming, metadata management, and real-time UI updates.
  • Economic Viability: Leveraging open-source technologies eliminates licensing overhead. The modular architecture reduces long-term maintenance costs, while cloud-native deployment options allow infrastructure expenses to scale proportionally with user demand.
  • Operational Viability: The interface prioritizes intuitive navigation and responsive design. Streamlined workflows for track uploading, playlist curation, and user account management minimize the learning curve, ensuring both administrators and end-users can interact with the platform efficiently.

Database Schema Design

Persistent storage is structured around relational tables optimized for media metadata and user interactions. The schema enforces data integrity through primary keys, unique constraints, and appropriate indexing strategies.

Column Name Data Type Length Constraint
track_id BIGINT - PRIMARY KEY
created_at TIMESTAMP - DEFAULT CURRENT_TIMESTAMP
audio_url VARCHAR 512 NOT NULL
title VARCHAR 255 NOT NULL
artist_name VARCHAR 128 DEFAULT NULL
duration_ms INT - DEFAULT NULL
genre_tag VARCHAR 64 DEFAULT NULL
play_count BIGINT - DEFAULT 0
uploader_id BIGINT - FOREIGN KEY
CREATE TABLE `app_users` (
  `user_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'Primary identifier',
  `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Record creation timestamp',
  `username` VARCHAR(100) NOT NULL COMMENT 'Unique login handle',
  `password_hash` VARCHAR(255) NOT NULL COMMENT 'Bcrypt encrypted credential',
  `display_name` VARCHAR(150) DEFAULT NULL COMMENT 'Public profile name',
  `email_address` VARCHAR(200) DEFAULT NULL COMMENT 'Contact email',
  `avatar_path` VARCHAR(512) DEFAULT NULL COMMENT 'Profile image URL',
  `account_status` TINYINT DEFAULT 1 COMMENT 'Active/Suspended flag',
  PRIMARY KEY (`user_id`),
  UNIQUE KEY `uk_username` (`username`),
  UNIQUE KEY `uk_email` (`email_address`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Platform user accounts';

CREATE TABLE `audio_tracks` (
  `track_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'Primary identifier',
  `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Upload timestamp',
  `uploader_id` BIGINT NOT NULL COMMENT 'Reference to app_users',
  `title` VARCHAR(255) NOT NULL COMMENT 'Track name',
  `storage_path` VARCHAR(512) NOT NULL COMMENT 'Object storage location',
  `mime_type` VARCHAR(100) DEFAULT 'audio/mpeg' COMMENT 'File format',
  `duration_seconds` INT DEFAULT NULL COMMENT 'Playback length',
  `is_public` BOOLEAN DEFAULT TRUE COMMENT 'Visibility setting',
  PRIMARY KEY (`track_id`),
  KEY `idx_uploader` (`uploader_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Music library catalog';

CREATE TABLE `auth_sessions` (
  `session_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'Primary identifier',
  `user_id` BIGINT NOT NULL COMMENT 'Associated account',
  `access_token` VARCHAR(512) NOT NULL COMMENT 'JWT or opaque token',
  `issued_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Generation time',
  `expires_at` TIMESTAMP NOT NULL COMMENT 'Validity deadline',
  `device_fingerprint` VARCHAR(255) DEFAULT NULL COMMENT 'Client identifier',
  PRIMARY KEY (`session_id`),
  KEY `idx_token` (`access_token`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Authentication tokens';

Core Implementation Logic

The backend exposes RESTful endpoints to handle media operations, authentication, and metadata retrieval. Service layers abstract business rules, while controllers manage HTTP request/response cycles.

@RestController
@RequestMapping("/api/v1/media")
@RequiredArgsConstructor
public class MediaCatalogController {

    private final TrackManagementService trackService;
    private final StorageGateway storageGateway;
    private final SecurityContextHelper securityHelper;

    @PostMapping("/upload")
    public ResponseEntity<ApiResponse<TrackDto>> ingestAudio(
            @RequestParam("file") MultipartFile audioFile,
            @RequestParam("title") String trackTitle,
            @RequestParam(value = "genre", required = false) String category) {
        
        if (audioFile.isEmpty() || !isValidAudioFormat(audioFile.getContentType())) {
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("Invalid or unsupported audio payload"));
        }

        String ownerId = securityHelper.extractCurrentUserId();
        String storageKey = storageGateway.persistBlob(audioFile, "tracks/" + ownerId);
        
        TrackEntity newRecord = TrackEntity.builder()
                .title(trackTitle)
                .genre(category)
                .storageLocation(storageKey)
                .uploaderId(ownerId)
                .uploadTimestamp(Instant.now())
                .build();

        TrackEntity saved = trackService.registerTrack(newRecord);
        return ResponseEntity.ok(ApiResponse.success(TrackMapper.toDto(saved)));
    }

    @GetMapping("/stream/{trackId}")
    public ResponseEntity<Resource> streamAudio(@PathVariable String trackId, HttpServletRequest request) {
        TrackMetadata metadata = trackService.fetchMetadata(trackId);
        if (metadata == null) {
            return ResponseEntity.notFound().build();
        }

        Resource audioResource = storageGateway.retrieveBlob(metadata.getStorageLocation());
        String mimeType = determineMimeType(metadata.getStorageLocation());
        
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(mimeType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + metadata.getTitle() + "\"")
                .body(audioResource);
    }

    private boolean isValidAudioFormat(String mime) {
        return mime != null && mime.startsWith("audio/");
    }

    private String determineMimeType(String path) {
        if (path.endsWith(".mp3")) return "audio/mpeg";
        if (path.endsWith(".wav")) return "audio/wav";
        if (path.endsWith(".flac")) return "audio/flac";
        return "application/octet-stream";
    }
}

Validation and Testing Strategy

Rigorous validation ensures system reliability and alignment with functional specifications. Black-box testing methodologies are applied across authentication flows and resource management modules. Test scenarios simulate boundary conditions, mandatory field omissions, and role-based access violations to uncover defects before production deployment.

Authentication Flow Validation

The login mechanism verifies credentials against hashed database records while enforcing captcha validation and role segregation. Incorrect inputs trigger precise error feedback without exposing sensitive system details.

Input Scenario Expected Outcome Actual Outcome Status
Valid user, correct password, valid captcha Grant access, issue session token Access granted, token generated Passed
Valid user, wrong password, valid captcha Reject login, show credential error Credential mismatch prompted Passed
Valid user, correct password, invalid captcha Block request, captcha error Captcha validation failed Passed
Empty username field Halt submission, require username Username required warning shown Passed
Admin credentials on standard user portal Deny access, privilege mismatch Unauthorized role access blocked Passed

Media Management Module Validation

Administrative functions cover track ingestion, metadata updates, and catalog removal. Validation rules enforce data completeness, prevent duplicate entries, and require explicit confirmation for destructive actions.

Input Scenario Expected Outcome Actual Outcome Status
Complete track metadata submission Persist record, reflect in catalog Track listed in management view Passed
Modify existing track genre/tag Update fields, retain other data Metadata successfully refreshed Passed
Trigger deletion on active track Prompt confirmation, remove record Record purged after confirmation Passed
Submit form with empty title field Reject save, highlight missing field Title mandatory error displayed Passed
Upload duplicate storage hash Reject operation, flag duplication Duplicate file warning triggered Passed

Test execution validates that all critical paths operate within defined parameters, error handling mechanisms trigger appropriately, and data persistence remains consistent across transaction boundaries.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.