본문 바로가기
Spring Boot

Spring Tag 라이브러리로 JSP include시 id 겹침 방지

by pswamazing 2025. 1. 3.

JSP Include 시 ID 중복 방지하는 법

안녕하세요! 오늘은 JSP를 include로 사용할 때 element id값이 겹쳐서 골치 아팠던 경험, 다들 있으시죠? 이 문제를 깔끔하게 해결하는 방법을 소개합니다!

여러분은 JSP include 시 ID 중복 문제를 어떻게 해결하고 계신가요? 댓글로 경험을 공유해주세요!


문제 상황

JSP를 include 해서 사용하다보면 element id값이 겹치는 경우가 많아 여간 골치아픈게 아닙니다. 같은 JSP 파일을 여러 번 include하면 동일한 id가 여러 개 생겨서 JavaScript나 CSS 선택자가 제대로 동작하지 않죠.

예를 들어 이런 상황입니다:

 
<!-- main.jsp -->
<jsp:include page="userForm.jsp"/>
<jsp:include page="userForm.jsp"/>

<!-- userForm.jsp 내부 -->
<input type="text" id="userName">  <!-- ID 중복 발생! -->

해결 방법: UUID 활용

Spring의 <s:eval> 태그와 UUID를 활용하면 이 문제를 깔끔하게 해결할 수 있습니다!


1. CommonUtils 유틸리티 클래스 생성

먼저 UUID를 생성하는 유틸리티 클래스를 만듭니다.

CommonUtils.java

package com.sw.common;

import java.util.UUID;

public class CommonUtils {
    
    public static String uuid() {
        return UUID.randomUUID().toString();
    }
}

코드 설명

UUID.randomUUID()는 전역적으로 고유한 식별자를 생성합니다. 예를 들어 "550e8400-e29b-41d4-a716-446655440000" 같은 형태의 문자열이 만들어지므로, 이를 id 값에 붙이면 절대 겹치지 않습니다.


2. Include를 선언하는 JSP 파일

include하는 쪽에서 UUID를 생성하고 파라미터로 전달합니다.

<%@ taglib prefix="s" uri="http://www.springframework.org/tags" %>

<s:eval var="pageUuid_popup" expression="T(com.sw.common.CommonUtils).uuid()"/>

<jsp:include page="${pageContext.request.contextPath}/WEB-INF/views/sw/popup/popup.jsp">
    <jsp:param name="pageUuid" value="${pageUuid_popup}"/>
</jsp:include>

s:eval 태그란?

<s:eval>은 Spring 태그 라이브러리(spring-form 태그라이브러리)에서 제공하는 태그입니다.

expression 속성 - 실행할 스프링 표현 언어(SpEL: Spring Expression Language) 표현식을 정의합니다.

var 속성 - 표현식의 실행 결과를 저장할 변수 이름을 지정합니다.

 

여러 개 include 하는 경우

<!-- 첫 번째 팝업 -->
<s:eval var="pageUuid_popup1" expression="T(com.sw.common.CommonUtils).uuid()"/>
<jsp:include page="/WEB-INF/views/sw/popup/popup.jsp">
    <jsp:param name="pageUuid" value="${pageUuid_popup1}"/>
</jsp:include>

<!-- 두 번째 팝업 -->
<s:eval var="pageUuid_popup2" expression="T(com.sw.common.CommonUtils).uuid()"/>
<jsp:include page="/WEB-INF/views/sw/popup/popup.jsp">
    <jsp:param name="pageUuid" value="${pageUuid_popup2}"/>
</jsp:include>

<!-- 세 번째 팝업 -->
<s:eval var="pageUuid_popup3" expression="T(com.sw.common.CommonUtils).uuid()"/>
<jsp:include page="/WEB-INF/views/sw/popup/popup.jsp">
    <jsp:param name="pageUuid" value="${pageUuid_popup3}"/>
</jsp:include>

이렇게 하면 같은 JSP를 여러 번 include해도 각각 다른 UUID를 가지게 되어 ID가 절대 겹치지 않습니다!


3. Include 되는 JSP 파일에서 ID 사용하기

include되는 JSP 파일에서는 전달받은 pageUuid를 활용하여 고유한 ID를 만듭니다.

popup.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="http://www.springframework.org/tags" %>

<!-- 파라미터로 전달받은 pageUuid 사용 -->
<div id="popup_container_${param.pageUuid}">
    <h2 id="popup_title_${param.pageUuid}">팝업 제목</h2>
    
    <form id="popup_form_${param.pageUuid}">
        <input type="text" name="user_name" id="user_name_${param.pageUuid}" placeholder="이름">
        <input type="email" name="user_email" id="user_email_${param.pageUuid}" placeholder="이메일">
        <button type="button" id="submit_btn_${param.pageUuid}">제출</button>
    </form>
    
    <button type="button" id="close_btn_${param.pageUuid}">닫기</button>
</div>

<script>
// JavaScript에서도 동일한 UUID 사용
document.getElementById('submit_btn_${param.pageUuid}').addEventListener('click', function() {
    var userName = document.getElementById('user_name_${param.pageUuid}').value;
    var userEmail = document.getElementById('user_email_${param.pageUuid}').value;
    
    console.log('이름:', userName);
    console.log('이메일:', userEmail);
});

document.getElementById('close_btn_${param.pageUuid}').addEventListener('click', function() {
    document.getElementById('popup_container_${param.pageUuid}').style.display = 'none';
});
</script>

 

실제 생성되는 HTML

위 코드가 실행되면 다음과 같이 고유한 ID가 생성됩니다:

<div id="popup_container_550e8400-e29b-41d4-a716-446655440000">
    <h2 id="popup_title_550e8400-e29b-41d4-a716-446655440000">팝업 제목</h2>
    
    <form id="popup_form_550e8400-e29b-41d4-a716-446655440000">
        <input type="text" id="user_name_550e8400-e29b-41d4-a716-446655440000">
        <input type="email" id="user_email_550e8400-e29b-41d4-a716-446655440000">
        <button type="button" id="submit_btn_550e8400-e29b-41d4-a716-446655440000">제출</button>
    </form>
</div>

실전 활용 예제

여러 개의 동일한 컴포넌트 사용하기

사용자 카드를 여러 개 표시하는 경우를 예로 들어보겠습니다.

<!-- userList.jsp -->
<%@ taglib prefix="s" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<h1>사용자 목록</h1>

<c:forEach items="${userList}" var="user">
    <s:eval var="cardUuid" expression="T(com.sw.common.CommonUtils).uuid()"/>
    <jsp:include page="/WEB-INF/views/components/userCard.jsp">
        <jsp:param name="pageUuid" value="${cardUuid}"/>
        <jsp:param name="userId" value="${user.id}"/>
        <jsp:param name="userName" value="${user.name}"/>
    </jsp:include>
</c:forEach>
 
 
<!-- userCard.jsp -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<div class="user-card" id="card_${param.pageUuid}">
    <h3 id="name_${param.pageUuid}">${param.userName}</h3>
    <button type="button" id="edit_btn_${param.pageUuid}">수정</button>
    <button type="button" id="delete_btn_${param.pageUuid}">삭제</button>
</div>

<script>
document.getElementById('edit_btn_${param.pageUuid}').addEventListener('click', function() {
    alert('${param.userName} 수정');
});

document.getElementById('delete_btn_${param.pageUuid}').addEventListener('click', function() {
    if(confirm('${param.userName}을(를) 삭제하시겠습니까?')) {
        // 삭제 로직
    }
});
</script>

 

모달 컴포넌트에 활용

<!-- main.jsp -->
<s:eval var="loginModalUuid" expression="T(com.sw.common.CommonUtils).uuid()"/>
<jsp:include page="/WEB-INF/views/modals/loginModal.jsp">
    <jsp:param name="pageUuid" value="${loginModalUuid}"/>
</jsp:include>

<s:eval var="signupModalUuid" expression="T(com.sw.common.CommonUtils).uuid()"/>
<jsp:include page="/WEB-INF/views/modals/signupModal.jsp">
    <jsp:param name="pageUuid" value="${signupModalUuid}"/>
</jsp:include>

장점 정리

ID 충돌 완전 방지 - UUID는 전역적으로 고유하므로 ID가 절대 겹치지 않습니다.

재사용성 향상 - 같은 JSP를 여러 번 include해도 문제없습니다.

유지보수 편리 - ID 규칙을 일일이 신경 쓸 필요가 없습니다.

JavaScript 오류 방지 - getElementById가 정확히 동작합니다.


주의사항

taglib 선언 필수

Spring 태그 라이브러리를 사용하려면 반드시 상단에 선언해야 합니다.

<%@ taglib prefix="s" uri="http://www.springframework.org/tags" %>

param vs request

include된 JSP에서 파라미터를 받을 때는 ${param.pageUuid} 형식을 사용합니다. ${pageUuid}로 쓰면 안 됩니다!

<!-- 올바른 방법 -->
<input type="text" id="input_${param.pageUuid}">

<!-- 잘못된 방법 -->
<input type="text" id="input_${pageUuid}">

CSS 선택자에도 활용

<style>
#container_${param.pageUuid} {
    background-color: #f5f5f5;
    padding: 20px;
}

#container_${param.pageUuid} .title {
    font-size: 24px;
    font-weight: bold;
}
</style>

마무리

이제 JSP include 시 ID 중복 걱정 없이 편하게 개발할 수 있습니다!

정리하면:

1단계 - CommonUtils 클래스에 UUID 생성 메서드 작성

2단계 - Include하는 JSP에서 s:eval로 UUID 생성

3단계 - jsp:param으로 UUID 전달

4단계 - Include되는 JSP에서 ${param.pageUuid}로 활용

정말 간단하죠? JSP 컴포넌트를 재사용할 때 이 방법을 활용해보세요!

댓글