Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Building a Fire Safety Education Site with SSM, JSP, and Vue

Tech May 8 3

Application Startup and Configuration

The entry point leverages Spring Boot’s auto-configuraton and MyBatis mapper scanning. The main class extends SpringBootServletInitializer to support traditional WAR deployment:

package com.platform;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
@MapperScan(basePackages = {"com.platform.mapper"})
public class SafetyEducationApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(SafetyEducationApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(SafetyEducationApplication.class);
    }
}

Account Management Endpoints

The controller exposes REST endpoints for registration, login, profile retrieval, password reset, and CRUD operations. User creation uses a timestamp combined with a random factor to generate identifiers.

package com.platform.controller;

import java.util.*;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import com.platform.entity.AccountEntity;
import com.platform.service.AccountService;
import com.platform.service.TokenService;
import com.platform.utils.*;

@RestController
@RequestMapping("/accounts")
public class AccountController {

    @Autowired
    private AccountService accountService;

    @Autowired
    private TokenService tokenService;

    @PostMapping("/signin")
    @IgnoreAuth
    public ApiResult signin(@RequestParam String loginName,
                            @RequestParam String secret,
                            HttpServletRequest request) {
        AccountEntity entity = accountService.lookupByLoginName(loginName);
        if (entity == null || !entity.getAccessKey().equals(secret)) {
            return ApiResult.fail("Invalid login name or access key");
        }
        String token = tokenService.issueToken(entity.getId(), loginName, "member", "member");
        return ApiResult.success().append("token", token);
    }

    @PostMapping("/signup")
    @IgnoreAuth
    public ApiResult signup(@RequestBody AccountEntity account) {
        if (accountService.existsByLoginName(account.getLoginAlias())) {
            return ApiResult.fail("Login name already registered");
        }
        long generatedId = new Date().getTime() + (long) (Math.random() * 10000);
        account.setId(generatedId);
        accountService.createAccount(account);
        return ApiResult.success();
    }

    @PostMapping("/signout")
    public ApiResult signout(HttpServletRequest request) {
        request.getSession().invalidate();
        return ApiResult.success("Signed out");
    }

    @GetMapping("/current")
    public ApiResult currentMember(HttpServletRequest request) {
        Long memberId = (Long) request.getSession().getAttribute("userId");
        AccountEntity entity = accountService.fetchById(memberId);
        return ApiResult.success().append("data", entity);
    }

    @PostMapping(value = "/reset-key")
    @IgnoreAuth
    public ApiResult resetKey(@RequestParam String loginName) {
        AccountEntity entity = accountService.lookupByLoginName(loginName);
        if (entity == null) {
            return ApiResult.fail("Login name does not exist");
        }
        entity.setAccessKey("safety123");
        accountService.modifyAccount(entity);
        return ApiResult.success("Access key reset to safety123");
    }

    @GetMapping("/list")
    @IgnoreAuth
    public ApiResult listPublic(@RequestParam Map<String, Object> filters,
                                AccountEntity query) {
        PageData page = accountService.fetchPage(filters, QueryHelper.buildPublicFilter(query, filters));
        return ApiResult.success().append("data", page);
    }

    @GetMapping("/admin-list")
    public ApiResult adminList(@RequestParam Map<String, Object> filters,
                               AccountEntity query) {
        PageData page = accountService.fetchPage(filters, QueryHelper.buildAdminFilter(query, filters));
        return ApiResult.success().append("data", page);
    }

    @GetMapping("/{entryId}")
    @IgnoreAuth
    public ApiResult detail(@PathVariable Long entryId) {
        AccountEntity entity = accountService.fetchById(entryId);
        return ApiResult.success().append("data", entity);
    }

    @PostMapping
    public ApiResult save(@RequestBody AccountEntity account) {
        if (accountService.countByLoginName(account.getLoginAlias()) > 0) {
            return ApiResult.fail("Login name already in use");
        }
        account.setId(new Date().getTime());
        accountService.createAccount(account);
        return ApiResult.success();
    }

    @Transactional
    @PutMapping
    public ApiResult modify(@RequestBody AccountEntity account) {
        if (accountService.countByLoginNameExceptSelf(account.getId(), account.getLoginAlias()) > 0) {
            return ApiResult.fail("Login name conflict");
        }
        accountService.modifyAccount(account);
        return ApiResult.success();
    }

    @DeleteMapping
    public ApiResult remove(@RequestBody Long[] ids) {
        accountService.removeBatch(Arrays.asList(ids));
        return ApiResult.success();
    }
}

Technology Stack Overview

Backend with Spring Boot

Spring Boot is the backbone for crafting standalone, production-grade applications on top of the Spring ecosystem. Its opinionated defaults and auto-configuration drastically cut boilerplate code. With embedded servlet containers like Tomcat, deployment turns into a simple java -jar command. Actuator endpoints enable runtime health checks and metrics. The starter dependencies and @SpringBootApplication annotation make it trivial to assemble a cohesive backend with persistence, security, and tarnsaction support.

Frontend with Vue

Vue.js offers a reactive data-binding core that simplifies dynamic enterface development. Its component architecture encourages breaking UIs into isolated, reusable pieces, which improves maintainability and testability. A vibrant plugin ecosystem and clear documentation accelerate both learning and feature delivery. Vue's progressive nature allows adopting it incrementally, making it suitable for anything from enhancing static pages to building complex single-page applications.

Testing Methodology

System validation aims to uncover discrepancies between actual behavior and specifications. Functional testing relies on black‑box techniques: boundary value analysis, mandatory field checks, and role-based authorization paths. For example, login scenarios include mismatched credentials, missing inputs, and cross‑role access attempts. Each test case is documented with expected outcomes, and failures trigger immediate investigation. This process ensures logical flow correctness and guards against regressions. Post‑test reviews confirm that the platform meets defined requirements without comfort‑impeding complexity, delivering a stable and intuitive experience for end users interacting with fire safety educational content.

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.