Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Developing a Tourism Information Management System with SSM Framework

Tech 3

Technology Stack Overview

  • Backend Language: Java
  • Core Architecture: SSM (Spring, SpringMVC, MyBatis)
  • View Layer: JSP
  • Persistence Layer: MyBatis
  • Application Server: Apache Tomcat (7/8/9/10)
  • Database Engine: MySQL (v5.7+)
  • Build Tool: Maven
  • Development Environment: IntelliJ IDEA / Eclipse

Core Feature Modules

Tourist Account Administration

Facilitates comprehensive oversight of tourist profiles. Administrators can execute precise or fuzzy queries based on client names, alongside standard operations for inserting, altering, and removing tourist records.

Travel Agency Directory

Provides an interface to oversee registered travel agencies. Management personnel can review published agency datasets, update existing entries, or invalidate records by deleting them from the system.

Tour Group Operations

Handles the lifecycle of travel groups. Features include conditional filtering to locate specific groups, aswell as the capability to instantiate, adjust, and inspect group configurations.

News Bulletin Management

Dedicated to handling informational bulletins. Administrators are equipped to draft new announcements, revise current news items, and search through the news archive.

Access Control and Cros-Origin Interceptor

package com.system.filter;

import com.system.annotation.PublicEndpoint;
import com.system.model.AccessToken;
import com.system.service.TokenVerificationService;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

@Component
public class AccessValidationInterceptor implements HandlerInterceptor {

    private static final String AUTH_HEADER = "X-Access-Token";

    @Autowired
    private TokenVerificationService verificationService;

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Credentials", "true");
        res.setHeader("Access-Control-Allow-Headers", "X-Requested-With, X-Access-Token, Origin, Content-Type, Accept, Authorization");
        res.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));

        PublicEndpoint endpointAnnotation = null;
        if (handler instanceof HandlerMethod) {
            endpointAnnotation = ((HandlerMethod) handler).getMethodAnnotation(PublicEndpoint.class);
        } else {
            return true;
        }

        if (endpointAnnotation != null) {
            return true;
        }

        String authToken = req.getHeader(AUTH_HEADER);
        AccessToken tokenData = null;
        if (authToken != null && !authToken.isEmpty()) {
            tokenData = verificationService.retrieveToken(authToken);
        }

        if (tokenData != null) {
            req.getSession().setAttribute("currentUserId", tokenData.getUserId());
            req.getSession().setAttribute("currentUserRole", tokenData.getRole());
            req.getSession().setAttribute("currentTable", tokenData.getTableName());
            req.getSession().setAttribute("currentUserAccount", tokenData.getAccountName());
            return true;
        }

        res.setCharacterEncoding("UTF-8");
        res.setContentType("application/json; charset=utf-8");
        PrintWriter out = res.getWriter();
        out.print(JSON.toJSONString(ResponseBuilder.unauthorized("Authentication required"))); 
        out.flush();
        out.close();
        return false;
    }
}

Account Management Controller

package com.system.controller;

import com.system.annotation.PublicEndpoint;
import com.system.model.SystemAccount;
import com.system.service.AccountService;
import com.system.service.TokenVerificationService;
import com.system.utils.ResponseBuilder;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Map;

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

    @Autowired
    private AccountService accountService;

    @Autowired
    private TokenVerificationService tokenService;

    @PublicEndpoint
    @PostMapping("/authenticate")
    public ResponseBuilder authenticate(String accountName, String secretKey, HttpServletRequest req) {
        SystemAccount account = accountService.selectOne(new EntityWrapper<SystemAccount>().eq("account_name", accountName));
        if (account == null || !account.getSecretKey().equals(secretKey)) {
            return ResponseBuilder.failure("Invalid credentials");
        }
        String generatedToken = tokenService.generateToken(account.getId(), accountName, "accounts", account.getRole());
        return ResponseBuilder.success().put("token", generatedToken);
    }

    @PublicEndpoint
    @PostMapping("/register")
    public ResponseBuilder register(@RequestBody SystemAccount account) {
        SystemAccount existing = accountService.selectOne(new EntityWrapper<SystemAccount>().eq("account_name", account.getAccountName()));
        if (existing != null) {
            return ResponseBuilder.failure("Account already registered");
        }
        accountService.insert(account);
        return ResponseBuilder.success();
    }

    @GetMapping("/terminateSession")
    public ResponseBuilder terminateSession(HttpServletRequest req) {
        req.getSession().invalidate();
        return ResponseBuilder.success("Session terminated");
    }

    @PublicEndpoint
    @PostMapping("/resetCredentials")
    public ResponseBuilder resetCredentials(String accountName) {
        SystemAccount account = accountService.selectOne(new EntityWrapper<SystemAccount>().eq("account_name", accountName));
        if (account == null) {
            return ResponseBuilder.failure("Account not found");
        }
        account.setSecretKey("default_pwd");
        accountService.update(account, null);
        return ResponseBuilder.success("Credentials reset to default");
    }

    @GetMapping("/fetchAll")
    public ResponseBuilder fetchAll(@RequestParam Map<String, Object> queryParams, SystemAccount account) {
        EntityWrapper<SystemAccount> wrapper = new EntityWrapper<>();
        Page<SystemAccount> resultPage = accountService.queryPage(queryParams, wrapper);
        return ResponseBuilder.success().put("dataset", resultPage);
    }

    @GetMapping("/fetchDetail/{id}")
    public ResponseBuilder fetchDetail(@PathVariable("id") Long id) {
        SystemAccount account = accountService.selectById(id);
        return ResponseBuilder.success().put("record", account);
    }

    @PostMapping("/persist")
    public ResponseBuilder persist(@RequestBody SystemAccount account) {
        SystemAccount duplicate = accountService.selectOne(new EntityWrapper<SystemAccount>().eq("account_name", account.getAccountName()));
        if (duplicate != null) {
            return ResponseBuilder.failure("Duplicate account name");
        }
        accountService.insert(account);
        return ResponseBuilder.success();
    }

    @PostMapping("/modify")
    public ResponseBuilder modify(@RequestBody SystemAccount account) {
        accountService.updateById(account);
        return ResponseBuilder.success();
    }

    @PostMapping("/remove")
    public ResponseBuilder remove(@RequestBody Long[] targetIds) {
        accountService.deleteBatchIds(Arrays.asList(targetIds));
        return ResponseBuilder.success();
    }
}
Tags: SSMJava

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.