Java SSM 기반 풍습 문화 관리 시스템: 명절, 식습관, 의복, 예의, 신앙, 건축 풍습 관리

목적

이 문서는 Java SSM 프레임워크를 활용한 풍습 문화 관리 시스템에 대해 다룹니다. 이 시스템은 명절, 식습관, 의복, 예의, 신앙, 건축 풍습 등 다양한 분야의 정보를 포함하며, 민속 문화의 보존, 계승 및 확산에 중요한 역할을 합니다.

SSM 프레임워크의 특징을 통해 효율적인 데이터 관리와 기능 구현이 가능합니다. 특히 명절 관리에서는 각 명절의 기원과 축하 방식 등을 상세히 기록하여 대중이 더 깊이 이해할 수 있도록 돕습니다. 또한 식문화 모듈은 전통 음식의 제조 방법을 제공하고, 의복 문화는 전통 의상의 특징과 변화 과정을 소개합니다. 예의 관련된 부분은 다양한 예절 절차를 명확히 규정하고, 신앙 문화는 그 내포된 의미를 설명합니다. 건축 문화는 사진과 글로 전통 건축 스타일을 묘사합니다.

기술 스택

백엔드 프레임워크 SSM

SSM(Spring, Spring MVC, MyBatis)는 개발 생산성을 크게 증대시킵니다. Spring은 의존성 주입과 트랜잭션 관리를 제공하고, Spring MVC는 웹 요청 처리 능력을 가지고 있으며, MyBatis는 데이터베이스 접근을 용이하게 합니다. 이러한 통합은 코드 유지보수와 확장성을 높이며, 성능 최적화에도 기여합니다.

프론트엔드 프레임워크 Vue.js

Vue.js는 가상 DOM(Virtual DOM)을 사용하여 효율적인 DOM 조작을 제공합니다. 데이터 바인딩과 컴포넌트 기반 아키텍처는 개발자에게 유연하고 효율적인 개발 환경을 제공하며, 자동 UI 업데이트는 데이터 처리에 집중할 수 있도록 합니다.

Spring

Spring은 객체 생성, 구성 및 생명주기 관리를 담당하는 컨테이너를 제공하며, 이를 통해 컴포넌트 간 결합도를 낮춥니다. SSM에서 Spring은 기본 프레임워크로서 다른 요소들을 통합하고 일관된 설정 관리를 제공합니다.

Spring MVC

Spring MVC는 MVC 패턴을 기반으로 한 웹 프레임워크입니다. DispatcherServlet이 요청을 처리하고 적절한 컨트롤러로 전달하며, 결과는 뷰 리졸버를 통해 사용자에게 반환됩니다. JSP나 Thymeleaf 같은 다양한 뷰 기술을 지원하며, 데이터 바인딩과 폼 검증 기능도 제공합니다.

MyBatis

MyBatis는 SQL 매핑을 제공하는 우수한 지속성 프레임워크입니다. Java 객체와 데이터베이스 간의 매핑을 설정해 데이터 조작을 간단하고 효과적으로 만듭니다. 동적 SQL과 캐싱 메커니즘을 지원하며, 성능을 더욱 향상시킵니다.

시스템 테스트

시스템 테스트는 사용자가 시스템을 이용할 때 발생할 수 있는 문제를 방지하기 위해 필수적입니다. 이를 통해 시스템의 기능 완전성과 논리의 정확성을 확인하고, 필요시 수정합니다. 모든 테스트는 사용자의 요구 사항을 중심으로 진행되어야 합니다.

로그인 기능 테스트

입력 데이터예상 결과실제 결과결과 분석
사용자명: admin, 비밀번호: 123456, 인증번호: 올바르게 입력시스템 로그인성공적으로 로그인됨예상대로 작동함
사용자명: admin, 비밀번호: 111111, 인증번호: 올바르게 입력비밀번호 오류 메시지 표시비밀번호 오류 메시지 표시예상대로 작동함
사용자명: admin, 비밀번호: 123456, 인증번호: 잘못 입력인증번호 오류 메시지 표시인증번호 오류 메시지 표시예상대로 작동함
사용자명: 공백, 비밀번호: 123456, 인증번호: 올바르게 입력사용자명 필수 메시지 표시사용자명 필수 메시지 표시예상대로 작동함

코드 예제


@PostMapping("/auth")
public ResponseEntity<Map<String, Object>> authenticateUser(@RequestBody AuthRequest request, HttpServletRequest httpRequest) {
    UserEntity user = userService.findUserByUsername(request.getUsername());
    
    if (user == null || !passwordEncoder.matches(request.getPassword(), user.getPassword())) {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Collections.singletonMap("message", "잘못된 사용자명 또는 비밀번호"));
    }

    String jwtToken = tokenService.generateJwt(user.getUserId(), user.getRole());
    Map<String, Object> response = new HashMap<>();
    response.put("token", jwtToken);
    return ResponseEntity.ok(response);
}

@Service
public class TokenService {

    public String generateJwt(Long userId, String role) {
        JwtToken token = findActiveTokenByUserId(userId);
        String jwt = UUID.randomUUID().toString();
        
        Calendar expiration = Calendar.getInstance();
        expiration.add(Calendar.HOUR_OF_DAY, 1);

        if (token != null) {
            token.setJwt(jwt);
            token.setExpiresAt(expiration.getTime());
            updateToken(token);
        } else {
            saveNewToken(new JwtToken(userId, role, jwt, expiration.getTime()));
        }
        
        return jwt;
    }
}

@Component
public class SecurityInterceptor implements HandlerInterceptor {

    @Autowired
    private TokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod method = (HandlerMethod) handler;
        if (method.getMethodAnnotation(IgnoreAuth.class) != null) {
            return true;
        }

        String jwt = request.getHeader("Authorization");
        if (StringUtils.isBlank(jwt)) {
            sendUnauthorizedResponse(response);
            return false;
        }

        JwtToken token = tokenService.validateToken(jwt);
        if (token == null) {
            sendUnauthorizedResponse(response);
            return false;
        }

        request.getSession().setAttribute("userId", token.getUserId());
        request.getSession().setAttribute("role", token.getRole());
        return true;
    }

    private void sendUnauthorizedResponse(HttpServletResponse response) throws IOException {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json");
        response.getWriter().write("{\"message\": \"먼저 로그인하세요\"}");
    }
}

데이터베이스 스키마


-- 토큰 테이블 구조
DROP TABLE IF EXISTS `jwt_tokens`;
CREATE TABLE `jwt_tokens` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL,
  `role` varchar(50) DEFAULT NULL,
  `jwt` varchar(255) NOT NULL,
  `issued_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `expires_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 샘플 데이터
INSERT INTO `jwt_tokens` VALUES (1, 1, 'admin', 'abc123xyz789', '2023-03-01 12:00:00', '2023-03-01 13:00:00');
INSERT INTO `jwt_tokens` VALUES (2, 2, 'user', 'def456uvw012', '2023-03-01 12:10:00', '2023-03-01 13:10:00');

태그: SSM Spring Vue.js

5월 25일 22:40에 게시됨