Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Interactive Movie Ticket Booking Platform: Spring Boot and Vue.js Implementation

Tech May 13 3

Technology Stack Overview

Backend Framework: Spring Boot

Spring Boot simplifies enterprise application development through convention-over-configuration principles. The framework eliminates boilerplate setup by embedding servlet containers like Tomcat or Jetty directly, enabling standalone deployment without external server installation. Its auto-configuration mechanism intelligently adapts to project dependencies, automatically wiring components based on classpath detection. This approach reduces manual configuration overhead while providing production-ready features such as metrics, health checks, and externalized configuration.

Frontend Framework: Vue.js

Vue.js employs a virtual DOM architecture for performant UI rendering. The framework's reactivity system establishes transparent dependency tracking between data models and view components. When application state mutates, the virtual DOM diffing algorithm calculates minimal DOM updates, ensuring efficient rendering cycles. Component-based composition combined with declarative templates enables building maintainable single-page applications with clear separation of concerns.

Data Access Layer: MyBatis-Plus

MyBatis-Plus extends MyBatis with enhanced CRUD operations and code generation capabilities. The library abstracts repetitive SQL patterns while preserving the flexibility of custom query construction. Its generator produces entity classes, mapper interfaces, and XML mappings from database schemas, accelerating development velocity. Additional features include pagination plugins, optimistic locking, and dynamic query wrappers that simplify complex data access scenarios.

Quality Assurance Strategy

Testing Methodology

Comprehensive validation encompasses functional verification, boundary condition analysis, and integration scenario simulation. Black-box testing techniques validate user-facing features without exposing implemantation details. Test cases cover authentication flows, data manipulation operations, and error handling pathways to ensure robust behavior under expected and edge-case inputs.

Authentication Module Validation

Login endpoint verification confirms credential validation, token generation, and session management. Tests simulate scenarios including valid credentials, password mismatches, verification code errors, and missing required fields.

Test Input Expected Behavior Actual Result Status
Valid credentials with correct verification Successful authentication Session token returned Pass
Correct username, incorrect password Authentication failure Error message displayed Pass
Valid credentials, wrong verification code Challenge rejected Verification error shown Pass
Empty username field Validation error "Username required" prompt Pass
Empty password field Authantication failure "Password required" prompt Pass

User Management Verification

User lifecycle operations undergo rigorous testing for data integrity and access control. Scenarios validate creation constraints, uniqueness enforcement, update propagation, and deletion confirmation workflows.

Operation Test Scenario Expected Outcome Result
Create user Complete valid data User appears in management list Pass
Modify user Update contact information Changes reflect immediately Pass
Delete user Confirm removal action Record permanently removed Pass
Create user Omit required fields Form validation triggers Pass
Create user Duplicate identifier Rejection with conflict message Pass

Implementation Reference

Authentication Controller

@RestController
@RequestMapping("/api/auth")
public class AuthenticationController {
    
    @Autowired
    private AccountService accountService;
    
    @Autowired
    private SessionService sessionService;
    
    @PermitAll
    @PostMapping("/authenticate")
    public ResponseEntity<AuthResponse> authenticate(@RequestBody LoginRequest credentials) {
        Account account = accountService.verifyCredentials(credentials.getUserId(), credentials.getPassword());
        
        if (account == null) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                .body(new AuthResponse("Invalid credentials"));
        }
        
        String sessionToken = sessionService.createSession(account.getId(), 
            account.getLoginName(), account.getEntityType(), account.getPrivilegeLevel());
        
        return ResponseEntity.ok(new AuthResponse(sessionToken));
    }
}

@Service
public class SessionService {
    
    private final SessionRepository sessionRepository;
    
    public String createSession(Long userId, String loginName, String entityType, String privilege) {
        SessionRecord existing = sessionRepository.findByUserIdAndPrivilege(userId, privilege);
        
        String tokenValue = UUID.randomUUID().toString().replace("-", "");
        Instant expiryTime = Instant.now().plus(1, ChronoUnit.HOURS);
        
        if (existing != null) {
            existing.setSessionKey(tokenValue);
            existing.setExpiresAt(expiryTime);
            sessionRepository.update(existing);
        } else {
            SessionRecord newSession = new SessionRecord(userId, loginName, entityType, 
                privilege, tokenValue, expiryTime);
            sessionRepository.insert(newSession);
        }
        
        return tokenValue;
    }
}

@Component
public class AuthenticationFilter implements Filter {
    
    private static final String AUTH_HEADER = "X-Session-Token";
    
    @Autowired
    private SessionService sessionService;
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        configureCors(httpResponse, httpRequest);
        
        if ("OPTIONS".equalsIgnoreCase(httpRequest.getMethod())) {
            httpResponse.setStatus(HttpStatus.OK.value());
            return;
        }
        
        if (isPublicEndpoint(httpRequest)) {
            chain.doFilter(request, response);
            return;
        }
        
        String token = httpRequest.getHeader(AUTH_HEADER);
        SessionRecord session = sessionService.validateToken(token);
        
        if (session != null && session.isActive()) {
            httpRequest.setAttribute("userId", session.getAccountId());
            httpRequest.setAttribute("privilege", session.getPrivilegeLevel());
            httpRequest.setAttribute("entityType", session.getEntityType());
            httpRequest.setAttribute("loginName", session.getLoginName());
            chain.doFilter(request, response);
        } else {
            httpResponse.setCharacterEncoding("UTF-8");
            httpResponse.setContentType("application/json");
            httpResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
            httpResponse.getWriter().write("{\"error\":\"Authentication required\"}");
        }
    }
    
    private void configureCors(HttpServletResponse response, HttpServletRequest request) {
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, X-Session-Token");
        response.setHeader("Access-Control-Max-Age", "3600");
    }
    
    private boolean isPublicEndpoint(HttpServletRequest request) {
        String path = request.getRequestURI();
        return path.startsWith("/api/auth/") || 
               request.getMethod().equals("GET") && path.startsWith("/api/public/");
    }
}

Database Schema

-- Session management table
DROP TABLE IF EXISTS `session_store`;
CREATE TABLE `session_store` (
  `record_id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Primary key',
  `account_id` BIGINT UNSIGNED NOT NULL COMMENT 'User identifier',
  `login_name` VARCHAR(100) NOT NULL COMMENT 'Account username',
  `entity_type` VARCHAR(50) DEFAULT NULL COMMENT 'Account classification',
  `privilege_level` VARCHAR(50) DEFAULT NULL COMMENT 'Access role',
  `session_key` VARCHAR(64) NOT NULL COMMENT 'Authentication token',
  `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Session creation time',
  `expires_at` TIMESTAMP NOT NULL DEFAULT '1970-01-01 00:00:01' COMMENT 'Session expiration time',
  PRIMARY KEY (`record_id`),
  UNIQUE KEY `uk_account_privilege` (`account_id`, `privilege_level`),
  KEY `idx_session_key` (`session_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='User session persistence';

-- Sample session records
INSERT INTO `session_store` VALUES 
(1, 101, 'john_doe', 'customer', 'standard', 'a1b2c3d4e5f6789012345678901234567890abcd', NOW(), DATE_ADD(NOW(), INTERVAL 1 HOUR)),
(2, 201, 'cinema_admin', 'partner', 'manager', 'b2c3d4e5f6789012345678901234567890abcde1', NOW(), DATE_ADD(NOW(), INTERVAL 2 HOUR)),
(3, 301, 'system_root', 'internal', 'administrator', 'c3d4e5f6789012345678901234567890abcde12f', NOW(), DATE_ADD(NOW(), INTERVAL 8 HOUR));

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...

SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller

Overview In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed...

Leave a Comment

Anonymous

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