SpringBoot 기반 학생 취업 관리 시스템 설계 및 구현

본 문서는 SpringBoot와 Vue를 활용한 학생 취업 정보 관리 시스템의 설계 및 구현 과정을 설명합니다. 전후방 분리 아키텍처를 채택하여 개발 효율성과 유지보수성을 높였으며, RESTful API 기반으로 데이터 통신을 수행합니다.

주요 기능 요약

  • 사용자 인증 및 권한 관리
  • 학생 정보 등록 및 조회
  • 취업 상태 추적 및 통계 제공
  • 웹소켓 기반 실시간 알림 기능
  • 민감 정보 자동 탈민감화 처리

핵심 코드 예제


/**
 * 사용자 비밀번호 초기화 엔드포인트
 */
@IgnoreAuth
@PostMapping("/init-password")
public ApiResponse initializePassword(
        @RequestParam("account") String account,
        HttpServletRequest request) {

    UserRecord user = userService.findUserByAccount(account);
    if (user == null) {
        return ApiResponse.error("해당 계정이 존재하지 않습니다.");
    }

    // 기본 비밀번호로 재설정 (암호화 적용)
    String defaultPwd = "123456";
    user.setPassword(EncryptionTool.encrypt(defaultPwd));
    userService.updateUser(user);

    return ApiResponse.success("비밀번호가 성공적으로 '123456'로 초기화되었습니다.");
}

/**
 * 페이징 기반 사용자 목록 조회 (관리자용)
 */
@GetMapping("/admin/users")
public ApiResponse getPagedUserList(
        @RequestParam Map queryParams,
        UserQueryCondition condition) {

    EntityWrapper<UserRecord> wrapper = new EntityWrapper<>();
    QueryUtil.buildSearchConditions(wrapper, condition, queryParams);

    PaginationResult result = userService.getPagedData(queryParams, 
        QueryUtil.sort(QueryUtil.applyFilters(wrapper, queryParams), queryParams));

    // 민감 필드 탈민감화 처리
    Map maskFields = Map.of("phone", "PHONE", "email", "EMAIL");
    DataMasker.anonymize(result, maskFields);

    return ApiResponse.ok("조회 성공", result);
}

/**
 * 일반 사용자용 목록 조회 (인증 불필요)
 */
@AnonymousAccess
@GetMapping("/public/users")
public ApiResponse getPublicUserList(
        @RequestParam Map params,
        UserQueryCondition queryObj) {

    EntityWrapper<UserRecord> filter = new EntityWrapper<>();
    QueryUtil.buildSearchConditions(filter, queryObj, params);

    PaginationResult pageData = userService.getPagedData(params, 
        QueryUtil.orderBy(QueryUtil.rangeFilter(QueryUtil.keywordMatch(filter, queryObj), params), params));

    DataMasker.anonymize(pageData, new HashMap<>());
    return ApiResponse.ok().setData(pageData);
}

/**
 * 웹소켓 메시지 수신 처리
 */
@OnMessage
public void handleMessage(String rawMessage) {
    log.info("WebSocket 수신: 세션 ID = {}, 메시지 = {}", this.session.getId(), rawMessage);

    if ("ping".equals(rawMessage.trim())) {
        sendResponse("pong", this.senderId, this.targetId);
    } else {
        broadcastMessage(rawMessage, this.senderId, this.targetId);
    }
}

/**
 * URL 쿼리 파라미터 파싱 유틸리티
 */
private Map parseQueryParameters(String queryString) {
    Map paramMap = new ConcurrentHashMap<>();
    if (queryString == null || queryString.isEmpty()) return paramMap;

    Arrays.stream(queryString.split("&"))
          .map(param -> param.split("=", 2))
          .forEach(pair -> {
              try {
                  String key = URLDecoder.decode(pair[0], StandardCharsets.UTF_8);
                  String value = (pair.length > 1) ? 
                      URLDecoder.decode(pair[1], StandardCharsets.UTF_8) : null;
                  paramMap.put(key, value);
              } catch (Exception e) {
                  log.warn("파라미터 디코딩 실패: {}", pair[0]);
              }
          });

    return paramMap;
}
    

데이터베이스 스키마 예시


DROP TABLE IF EXISTS `system_log`;
CREATE TABLE `system_log` (
  `log_id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '로그 식별자',
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '기록 시간',
  `user_id` VARCHAR(255) NOT NULL COMMENT '사용자 ID',
  `action` TEXT COMMENT '수행 작업',
  `request_method` VARCHAR(100) COMMENT 'HTTP 메서드',
  `request_params` LONGTEXT COMMENT '요청 파라미터',
  `duration_ms` BIGINT COMMENT '처리 시간(밀리초)',
  `client_ip` VARCHAR(100) COMMENT '클라이언트 IP 주소',
  INDEX idx_user_time (`user_id`, `created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='시스템 동작 로그';
    

기술 스택 설명

SpringBoot: 스프링 생태계 기반 자바 백엔드 프레임워크로, 자동 구성(auto-configuration), 내장 서버, 스타터 의존성 등을 통해 신속한 서비스 개발이 가능합니다. 복잡한 XML 설정 없이 애너테이션 기반으로 간결하게 구성할 수 있으며, 단일 JAR 파일로 배포가 가능한 독립 실행형 애플리케이션을 생성합니다.

Vue.js: 점진적으로 채택 가능한 프론트엔드 프레임워크로, 반응형 데이터 바인딩과 컴포넌트 기반 UI 개발을 지원합니다. 가상 DOM 기반 렌더링과 간결한 템플릿 문법을 통해 직관적인 뷰 개발이 가능하며, Vue Router와 Pinia를 조합하면 완전한 SPA 애플리케이션 구축이 가능합니다.

전후방 분리 아키텍처를 통해 각 계층의 독립성을 확보하고, JSON 기반 REST API로 HTTP 통신을 수행함으로써 유연한 시스템 확장과 팀별 병렬 개발이 가능합니다.

태그: SpringBoot Vue.js RESTful API 학생관리시스템 백엔드개발

6월 2일 23:08에 게시됨