minari0v0
소개프로젝트스토리

© 2026 minari0v0. All rights reserved.

모든 프로젝트GitHub 저장소

텅장수강러

대학생들을 위한 강의 평가 및 정보 공유 커뮤니티

JavaJSPServletMySQLjQueryBootstrapChart.js
텅장수강러
개발 기간
2025년 4월~2025년 6월
프로젝트 유형
개인 프로젝트
기술 스택 (Tech Stack)
Frontend
JSPBootstrap
Backend
JavaServlet
Database
MySQL
Others
jQueryChart.js

프로젝트 개요

"이번 학기 시간표, 또 망하셨나요?" 수강신청 '광클' 실패로 인한 절망, 오늘 학식 메뉴에 대한 고민, 흩어진 학사 정보들...

'텅장수강러'는 대학생의 지갑(텅장)만큼이나 공허할 뻔한 대학 생활을 알차게 채우기 위해 시작된 프로젝트입니다. 단순히 시간표를 짜는 도구를 넘어, 대학생의 하루를 책임지는 올인원 캠퍼스 라이프 플랫폼을 지향합니다.

여기저기 흩어진 학교 정보를 찾아 헤매는 불편함을 없애기 위해, 강의 평가와 시간표 관리부터 실시간 학식 정보, 학사 일정, 그리고 익명 커뮤니티까지 대학 생활에 필수적인 모든 기능을 하나의 직관적인 웹 애플리케이션에 담았습니다.

프로젝트 구조

.
├── pom.xml
└── src
    ├── main
    │   ├── java/com/minari/tungzang
    │   │   ├── controller (서블릿 컨트롤러: 요청 처리 및 뷰 디스패치/JSON 응답)
    │   │   ├── dao (데이터베이스 접근 객체: JDBC를 통한 CRUD 및 쿼리)
    │   │   ├── model (데이터 모델: POJO 정의)
    │   │   ├── service (비즈니스 로직: DAO 오케스트레이션 및 비즈니스 규칙 적용)
    │   │   ├── filter (서블릿 필터: 인증, 인코딩 처리)
    │   │   ├── listener (컨텍스트 리스너: 애플리케이션 생명 주기 관리, DB 드라이버 정리)
    │   │   └── util (유틸리티 클래스: DB 연결, JSON, 비밀번호 해싱, 태그 분석, 유효성 검사)
    │   ├── resources
    │   │   └── database.sql (DB 스키마 및 샘플 데이터)
    │   └── webapp
    │       ├── WEB-INF
    │       │   └── views (JSP 뷰 파일: 헤더, 푸터, 각종 페이지 템플릿)
    │       ├── resources (CSS, JS, 이미지 등 정적 리소스)
    │       └── *.jsp (메인, 로그인, 시간표 등 사용자 인터페이스)
    └── test

기술 스택 및 아키텍처

분류기술
FrontendHTML/CSS/JS, Bootstrap 5, jQuery, Chart.js
BackendJava 8, Servlet / JSP
DatabaseMySQL 8.0
ServerApache Tomcat 9.0
Librariesjbcrypt, Gson, Jackson, Jsoup
ToolsMaven, IntelliJ IDEA, MySQL Workbench

DB 설계

주요 테이블

-- 사용자 정보
users (id, username, password, name, email, department, student_id, is_admin, grade)
 
-- 강의 정보 (평가 통계 포함)
courses (id, name, professor, department, type, rating, evaluation_count, difficulty, homework, team_project, exam_count, is_popular)
 
-- 강의 태그 (다대다 관계)
course_tags (id, course_id, tag)
 
-- 강의 평가
evaluations (id, course_id, user_id, rating, difficulty, homework, course_type, comment, team_project, is_reported)
 
-- 강의 평가 특성 (다대다 관계)
evaluation_features (id, evaluation_id, feature)
 
-- 게시글
posts (id, title, content, category, author_id, likes, comment_count, views, is_hot, is_reported)
 
-- 댓글
comments (id, post_id, author_id, content, likes, is_reported)
 
-- 시간표 강의
timetable_courses (id, user_id, name, professor, day, start_time, end_time, location, color)
 

UI/UX 특징

모던함과 반응형 디자인

  • 반응형 웹 디자인: Bootstrap 5 기반, 다양한 디바이스 최적화
  • 다크 모드 지원: CSS 변수와 prefers-color-scheme 활용

동적이고 직관적인 인터페이스

  • 드래그 앤 드롭 시간표: jQuery & JS 기반, 직관적 강의 배치
  • 활동 기반 배지/등급 시스템: 사용자 참여 유도, 시각적 보상
  • 검색 가능 드롭다운: 긴 목록 필터링 및 선택 편의성 증대
  • AJAX 비동기 상호작용: 부드러운 페이지 전환 및 실시간 데이터 업데이트

정보 제공의 효율성

  • 캠퍼스 정보 통합: 날씨(OpenWeatherMap), 학식(Jsoup), 학사 일정(크롤링)
  • 자동 태그 생성: 강의 평가 기반 키워드 태그 자동화

주요 기능

1. 스마트 시간표 관리

  • 드래그 앤 드롭 인터페이스로 강의를 추가, 이동, 수정하여 나만의 시간표를 구성
  • 요일별/시간별 그리드 뷰와 목록 뷰 제공
  • 시간표 강의별 색상 커스터마이징 기능
  • 핵심 기술: TimetableServlet (CRUD API), TimetableService, TimetableDAO, timetable.js (프론트엔드 상호작용)

Screenshot_Schedule 시간표 관리 페이지 - 드래그 앤 드랍을 통한 간편한 수정 Screenshot_Schedule

2. 집단지성 강의 평가 시스템

  • 강의별 평점, 난이도, 과제량 등 상세한 지표와 사용자의 댓글 평가를 제공
  • 강의 평가 내용을 자동 분석하여 태그 생성 및 표시
  • 평가 조회, 작성, 수정, 삭제 기능 및 좋아요, 신고 기능
  • 핵심 기술: EvaluationsServlet, EvaluationApiServlet (API), EvaluationService, EvaluationDAO, CourseService, CourseDAO, TagAnalyzer (태그 분석)

Screenshot_evaluation 강의평가 목록 화면 - 등록된 강의평가 확인

3. 활발한 학생 커뮤니티

  • 자유게시판, 정보 공유, 스터디 모집 등 다양한 카테고리의 게시판
  • 게시글 및 댓글 작성, 수정, 삭제, 좋아요, 조회수 증가, 인기 게시글 기능
  • 핵심 기술: CommunityServlet, PostsServlet, CommentsServlet, PostService, CommentService, PostDAO, CommentDAO

Screenshot_Community 커뮤니티 화면 - 좋아요를 통한 인기글, 카테고리별 게시판

4. 캠퍼스 생활 정보 허브

  • 실시간 날씨: OpenWeatherMap API 연동, 안양대학교 기준 날씨 및 5일 예보
  • 학식 메뉴: Jsoup 웹 크롤링을 통해 안양대학교 공식 홈페이지에서 학식 메뉴 정보 수집
  • 학사 일정: 안양대학교 공식 홈페이지의 AJAX 엔드포인트에서 학사 일정 데이터 파싱 및 가공
  • 핵심 기술: CampusLifeServlet, Jsoup, OpenWeatherMap API, JSON 파싱

Screenshot_InfoHub_날씨 Screenshot_InfoHub_학식 Screenshot_InfoHub_일정 생활 정보 화면 - API, 크롤링을 통해 한 곳에서 모든 정보 확인 가능

5. 관리자 대시보드

  • 사용자, 게시글, 강의평가 등 사이트 전반의 활동 현황을 시각적 차트(Chart.js)로 제공
  • 신고된 게시물, 댓글, 강의평가를 확인하고 처리(삭제/무시)하는 기능
  • 사용자 관리, 강의 태그 일괄 업데이트 등 운영 기능
  • 핵심 기술: AdminServlet, AdminReportServlet, Chart.js, UserDAO, PostService, CommentService, EvaluationService

Screenshot_AdminDash 관리자 대시보드 - Chart.js를 활용한 사용자 통계, 게시물 현황, 데이터 시각화

핵심 기술

1. 동적 시간표 관리를 위한 RESTful API 및 클라이언트 구현

사용자 시간표는 TimetableServlet의 RESTful API를 통해 관리됩니다. 클라이언트(timetable.js)는 AJAX 요청(GET, POST, PUT, DELETE)을 보내 시간표 데이터를 비동기적으로 처리하고, 드래그 앤 드롭 UI를 통해 사용자가 직관적으로 강의를 추가/수정/이동할 수 있도록 합니다.

// Controller: TimetableApiServlet.java - 새로운 시간표 강의 추가 (POST 요청)
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // ... 사용자 인증 및 JSON 데이터 파싱 ...
    User user = (User) session.getAttribute("user");
    JSONObject jsonData = new JSONObject(jsonBuilder.toString());
 
    TimetableCourse course = new TimetableCourse();
    course.setUserId(user.getId());
    course.setName(jsonData.getString("name"));
    course.setProfessor(jsonData.getString("professor"));
    // ... 기타 속성 설정 ...
 
    // Service 계층 호출
    int courseId = timetableService.addTimetableCourse(course);
 
    if (courseId > 0) {
        course.setId(courseId);
        JSONObject jsonCourse = convertTimetableCourseToJson(course);
        response.setStatus(HttpServletResponse.SC_CREATED);
        response.getWriter().print(jsonCourse.toString());
    } else {
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        response.getWriter().print("{\"error\": \"시간표 강의 저장에 실패했습니다.\"}");
    }
}
// Frontend: timetable.js - 강의 추가 폼 제출 (AJAX POST)
function submitCourseForm(form, action) {
    const formData = new FormData(form)
    const courseData = {}
    formData.forEach((value, key) => { courseData[key] = value })
 
    const url = action === "add" ? contextPath + "/api/timetable/courses" : contextPath + "/api/timetable/courses/" + courseData.id
    const method = action === "add" ? "POST" : "PUT"
 
    fetch(url, {
        method: method,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(courseData),
    })
    .then(response => { /* ... 응답 처리 ... */ })
    .catch(error => { /* ... 오류 처리 ... */ })
}

2. JDBC 트랜잭션 기반의 데이터 일관성 관리

댓글 좋아요 토글과 같은 복합적인 데이터 변경 작업(좋아요 기록 추가/삭제, 게시글 좋아요 수 업데이트)은 JDBC 트랜잭션으로 묶어 데이터의 원자성(Atomicity)과 일관성(Consistency)을 보장합니다.

// Service: CommentService.java - 댓글 좋아요 토글
public boolean toggleCommentLike(int commentId, int userId) {
    Connection conn = null;
    boolean liked = false;
    try {
        conn = DatabaseUtil.getConnection();
        conn.setAutoCommit(false); // 트랜잭션 시작
 
        // 1. comment_likes 테이블에서 좋아요 여부 확인 및 추가/삭제
        // 2. comments 테이블의 likes 컬럼 업데이트 (증가 또는 감소)
 
        conn.commit(); // 성공 시 커밋
    } catch (SQLException e) {
        if (conn != null) conn.rollback(); // 오류 발생 시 롤백
        // ... 로깅 및 예외 처리 ...
    } finally {
        if (conn != null) conn.setAutoCommit(true); // 자동 커밋 모드 복원
        DatabaseUtil.close(conn);
    }
    return liked;
}

3. 사용자 활동 기반의 업적 (등급 및 배지 시스템)

사용자 등급은 강의 평가, 게시글 작성, 댓글 작성, 시간표 등록 등 활동 내역의 총합을 기준으로 동적으로 계산됩니다. UpdateUserGrade 스토어드 프로시저와 BadgeService를 통해 배지를 부여하고, 이를 시각적으로 화려하게 표현하여 사용자 참여를 유도합니다. 등급 뱃지

-- MySQL Stored Procedure: UpdateUserGrade
CREATE PROCEDURE UpdateUserGrade(IN p_user_id INT)
BEGIN
    DECLARE v_total_activity INT DEFAULT 0;
    -- ... 각 활동별 개수 조회 ...
    SET v_total_activity = v_evaluation_count + v_post_count + v_comment_count + v_timetable_count;
 
    -- 등급 결정 로직
    IF v_total_activity >= 100 THEN SET v_new_grade = '마스터';
    ELSEIF v_total_activity >= 50 THEN SET v_new_grade = '전문가';
    -- ...
    ELSE SET v_new_grade = '새내기';
    END IF;
 
    UPDATE users SET grade = v_new_grade WHERE id = p_user_id;
END //
/* CSS: badge-collection.css - 관리자 등급 배지 애니메이션 */
.grade-badge.tier-관리자 {
    background: var(--tier-admin-animated); /* 무지개 그라데이션 애니메이션 */
    background-size: 400% 400%;
    animation: adminBadgeRotate 3s linear infinite, adminBadgePulse 2s ease-in-out infinite;
    /* ... 기타 스타일 및 애니메이션 ... */
}

프로젝트 성과

기술적 성장

  • 풀스택 웹 애플리케이션 개발: 백엔드(Java Servlet/JSP, JDBC)부터 프론트엔드(HTML/CSS/JS, jQuery, Bootstrap)까지 전반적인 웹 개발 프로세스 및 MVC 아키텍처 이해
  • 데이터베이스 설계 및 관리: 복잡한 엔티티 관계(1:N, N:M), 외래 키 제약 조건, 트랜잭션, 저장 프로시저를 활용한 견고한 DB 스키마 설계 및 효율적인 데이터 관리 능력
  • AJAX 기반 비동기 통신: jQuery와 Fetch API를 활용하여 RESTful API를 구축하고, 페이지 새로고침 없는 동적인 UI 구현 경험
  • 외부 API 및 웹 크롤링: OpenWeatherMap API 연동 및 Jsoup을 이용한 웹 크롤링을 통해 외부 데이터 통합 및 처리 능력 향상
  • 보안 구현: 비밀번호 해싱(jbcrypt), 인증 필터, 입력 유효성 검사 등 웹 보안 기초 요소 적용

문제 해결 경험

  • 복잡한 UI 상호작용 구현: 드래그 앤 드롭 시간표, 검색 가능한 드롭다운, 동적인 배지 시스템 등 사용자 친화적인 UI 구현 과정에서의 논리 설계 및 디버깅 경험 드롭다운_검색
  • 데이터 일관성 유지: 트랜잭션을 활용하여 여러 테이블에 걸친 데이터 변경 작업(좋아요 토글, 강의 평가 추가/삭제)의 원자성 보장
  • 성능 최적화: 대량의 데이터(강의 평가, 게시글) 조회 시 효율적인 쿼리 설계 및 페이지네이션/필터링 구현
  • 유지보수성 고려: CSS 변수, 모듈화된 JavaScript, JSTL 활용 등을 통해 코드의 재사용성과 유지보수성 향상

개선할 부분

대학 강의 프로젝트이기에 JSP와 jQuery 기반의 전통적인 방식이지만, 추후에 백엔드는 Spring Boot, 프론트엔드는 React/Vue.js와 같은 현대적인 프레임워크로 전환하여 개발 생산성과 모듈성을 극대화할 수 있을 것 같다. 또한, Docker를 이용한 컨테이너화 및 CI/CD 파이프라인 구축을 통해 배포 프로세스를 자동화하고 서비스 확장성을 고려한 아키텍처로 발전시킬 수 있습니다.

프로젝트 회고

'텅장수강러'는 웹 개발의 세계에 첫 발을 내딛으며, "웹 애플리케이션은 어떻게 작동하는가?"라는 근원적인 질문에 답을 찾아가는 과정이었습니다.

Spring과 같은 편리한 프레임워크를 사용하기에 앞서, 순수 Java와 표준 웹 기술만으로 MVC 패턴을 직접 설계하고 구현해 본 경험은 개발자로서 더할 나위 없이 소중한 자산이 되었습니다. 데이터의 흐름을 날것 그대로 제어하며 프론트엔드와 백엔드가 유기적으로 연결되는 과정을 직접 부딪쳐본 덕분에, 풀스택 개발의 매력과 필요성을 몸소 체감할 수 있었습니다.

이 프로젝트에서 쌓아 올린 '날 것의 경험'은 향후 Spring Boot와 같은 모던 프레임워크를 단순히 사용하는 것을 넘어, "프레임워크가 내부적으로 어떤 문제를 해결해주고 있는지"를 깊이 있게 이해하고 활용할 수 있는 단단한 기반이 될 것이라 확신합니다.

다른 프로젝트 둘러보기

이전 프로젝트Java 소켓 기반 온라인 오목 게임
다음 프로젝트PassCheckers