관리 메뉴

거니의 velog

(7) 자바 코드를 없애는 액션 태그 1 본문

Java/Java_JSP

(7) 자바 코드를 없애는 액션 태그 1

Unlimited00 2023. 9. 11. 20:54

* JSP가 등장하게 된 배경은 디자이너가 자바 코드를 사용하지 않고도 쉽게 화면을 구현할 수 있도록 하기 위함이었다고 했다. 하지만 화면이 점차 복잡해지면서 디자이너들은 상황에 따라 HTML 태그에 자바 코드를 같이 써야 하는 문제로 어려움을 겪게 되었다. 따라서 JSP는 스크립트릿의 자바 코드를 제거하고 디자이너 입장에서 더 쉽고 편리하게 작업할 수 있는 태그 형태로 기능을 제공하게 되었고, 다음과 같은 액션 태그들로 자바 코드를 대신하게 되었다.

<JSP의 여러 가지 액션 태그>

이름 형식 설명
인클루드 액션 태그 <jsp:include> 이미 있는 JSP를 현재 JSP에 포함하는 태그
포워드 액션 태그 <jsp:forward> 서블릿에서 RequestDispatcher 클래스의 포워딩 기능을 대신하는 태그
유즈빈 액션 태그 <jsp:useBean> 객체를 생성하기 위한 new 연산자를 대신하는 태그
셋프로퍼티 액션 태그 <jsp:setProperty> setter를 대신하는 태그
겟프로퍼티 액션 태그 <jsp:getProperty> getter를 대신하는 태그

1. 인클루드 액션 태그 사용하기

* 인클루드 액션 태그(Include Action Tag)는 지난 번에 사용한 인클루드 디렉티브 태그처럼 화면을 분할해서 관리할 때 사용한다. 우선 다음 예시를 통해 알아보자. 처음 메인 페이지를 요청하면 상단 화면이 포함되어 나타난다.

* 그리고 상품을 클릭하면 상세 페이지가 나타나면서 상단 화면은 그대로 재사용한다.

* 인클루드 액션 태그를 이용하면 이처럼 공통적으로 사용하는 홈페이지의 상단 화면을 재사용할 수 있다.

* 인클루드 액션 태그의 형식은 다음과 같다.

<jsp:include page="jsp페이지" flush="true 또는 false">
	...
</jsp:include>

* 여기서 page는 포함할 JSP 페이지를 의미한다. 그리고 flush는 지정한 JSP를 실행하기 전 출력 버퍼 비움 여부를 지정한다.

* 그럼 인클루드 액션 태그와 인클루드 디렉티브 캐그의 차이점은 무엇일까?

<인클루드 액션 태그와 인클루드 디렉티브 태그 비교>

항목 인클루드 액션 태그 인클루드 디렉티브 태그
기능 JSP 레이아웃 모듈화 JSP 레이아웃 모듈화
처리 시간 요청 시간에 처리 JSP를 자바 코드로 변환 시 처리
데이터 처리 방법 param 액션 태그를 이용해 동적 처리 가능 정적 처리만 가능
포함된 JSP 자바 파일 변환 여부 포함되는 JSP가 각각 자바 파일로 생성 포함되는 JSP가 포함하는 JSP에 합쳐진 후 한개의 자바 파일로 생성

(1) JSP 페이지에 이미지 포함 실습

* 인클루드 액션 태그를 사용해 실습해 보자.

1. 새 프로젝트 pro13을 만들고 다음과 같이 실습에 필요한 이미지 파일(duke.png, duke2.png)과 duke_image.jsp, include.jsp, include2.jsp 파일을 추가한다.

* 인클루드 액션 태그의 실행 과정은 다음과 같다.

1. 브라우저 요청 시 JSP 파일을 컴파일한다.

2. 컴파일 시 <jsp:include>가 지시하는 JSP를 요청한다.

3. 요청된 JSP를 컴파일한다.

4. 컴파일된 JSP가 응답을 보낸다.

5. JSP는 브라우저에서 요청한 응답 결과를 출력한다.

2. 자식 JSP에 해당하는 duke_image.jsp를 다음과 같이 작성한다. 부모 JSP에서 포함 요청 시 전달되는 이름과 이미지 파일을 getParameter() 메서드를 이용해 가져온 후 이름과 해당 이미지를 출력한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
   request.setCharacterEncoding("utf-8");
   String name = request.getParameter("name");
   String imgName = request.getParameter("imgName");
   // param 액션 태그로 전달된 매개변수를 getParameter() 메서드를 이용해 가져온다.
%>

<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>듀크이미지</title>
    </head>

    <body>
        <br><br>
        <h1>이름은 <%= name%>입니다. </h1><br><br>
        <img src="./image/<%=imgName %>" />
    </body>

</html>

3. 부모 JSP인 include1.jsp를 다음과 같이 작성한다. <jsp:include> 태그의 page 속성에 포함할 자식 JSP인 duke_image.jsp 를 지정한다. 그리고 <jsp:param> 태그(param 액션 태그)를 이용해 이름과 이미지 파일 이름을 동적으로 자식 JSP인 duke_image.jsp로 포워딩 한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	request.setCharacterEncoding("utf-8");
%>

<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>include1.jsp</title>
    </head>

    <body>
        안녕하세요. 쇼핑몰 중심 JSP 시작입니다!!!
        <br>
        <!-- duke_image.jsp를 동적으로 포워딩한다. -->
        <jsp:include page="duke_image.jsp" flush="true">
            <jsp:param name="name" value="듀크" />
            <jsp:param name="imgName" value="duke.png" />
        </jsp:include>
        <!-- param 액션 태그를 이용해 duke_image.jsp로 이름과 파일 이름을 전달한다. -->
        <br>
        안녕하세요. 쇼핑몰 중심 JSP 끝 부분입니다.!!!
    </body>

</html>

4. 이번에는 다른 부모 JSP인 include2.jsp를 다음과 같이 작성한다. 자식 JSP로 다른 이름과 이미지 파일 이름을 전달한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
   request.setCharacterEncoding("utf-8");
%>

<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>include2.jsp</title>
    </head>

    <body>
        안녕하세요. 쇼핑몰 중심 JSP 시작입니다!!!
        <br>
        <jsp:include page="duke_image.jsp" flush="true">
            <jsp:param name="name" value="듀크2" />
            <jsp:param name="imgName" value="duke2.png" />
        </jsp:include>
        <!-- param 액션 태그를 이용해 duke_image.jsp로 이름과 파일 이름을 전달한다. -->
        <br>
        안녕하세요. 쇼핑몰 중심 JSP 끝 부분입니다.!!!
    </body>

</html>

5. 브라우저에서 JSP 파일을 요청하면 각각 다른 이미지와 이름이 출력된다. 먼저 다음의 주소로 요청한다.

- http://localhost:8090/pro13/include1.jsp

6. 다음의 주소로 요청하면 앞에서와는 다른 이미지와 이름이 출력되는 것을 볼 수 있다.

- http://localhost:8090/pro13/include2.jsp

* 이처럼 인클루드 액션 태그는 포함되는 자식 JSP에 데이터를 동적으로 전달해서 원하는 결과를 출력할 수 있다.

7. 다음 경로의 윈도 탐색기로 가면 JSP 파일이 자바 파일로 변환된 것을 볼 수 있다.

- D:\A_TeachingMaterial\01_BasicJava\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\pro13\org\apache\jsp

8. 인클루드 액션 태그로 요청한 include1.jsp의 자바 파일을 열어보자. <jsp:param> 태그로 전달한 매개변수들이 자식 JSP로 전달된다.

* 인클루드 디렉티브 태그와 인클루드 액션 태그의 실행 결과는 같지만 두 기능의 차이점은 어떤 것인지 알아두어야 한다.


2. 포워드 액션 태그 사용하기

* 서블릿에서 다른 서블릿으로 포워딩하는 방법에 RequestDispatcher를 이용하는 방법이 있다. 하지만 포워드 액션 태그를 사용하면 자바 코드 없이도 포워딩 할 수 있다. 또한 포워딩 시 다른 서블릿이나 JSP로 값을 전달할 수도 있다.

* 포워드 액션 태그의 형식은 다음과 같다.

<jsp:forward page ="포워딩할 JSP 페이지">
	...
</jsp:forward>

* 그럼 포워드 액션 태그를 다음 예제로 실습해 보자.

1. 다음과 같이 실습 파일 login.jsp, result.jsp를 생성한다.

2. 로그인창에서 ID와 비밀번호를 입력한 후 action의 result.jsp로 전달하도록 login.jsp를 작성한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
   request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>로그인창</title>
    </head>

    <body>
        <h1>아이디를 입력하지 않았습니다. 아이디를 입력해 주세요. </h1>
        <form action="result.jsp" method="post">
            아이디: <input type="text" name="userID"><br>
            비밀번호: <input type="password" name="userPw"><br>
            <input type="submit" value="로그인">
            <input type="reset" value="다시입력">
        </form>
    </body>

</html>

3. ID를 입력하지 않은 경우 자바의 RequestDispatcher를 사용하지 않고 포워드 액션 태그를 사용해 다시 로그인창으로 이동하도록 result.jsp를 작성한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%
   request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>결과창</title>
    </head>

    <body>
        <%
	       String userID = request.getParameter("userID");
	       if(userID.length()==0){
	        /*
	          RequestDispatcher dispatch = request.getRequestDispatcher("login.jsp");  
	          dispatch.forward(request, response);
	        */  // RequestDispatcher 를 사용해 포워딩 하지 않아도 된다.
	    %>
	    <!-- ID를 입력하지 않았으면 다시 jsp:forward 태그를 사용해 로그인 창으로 포워딩한다. -->
        <jsp:forward page="login.jsp" />
        <%	
	      }
	    %>
        <h1>환영합니다 <%= userID %>님!! </h1>
    </body>

</html>

4. 다음의 주소로 요청하여 ID와 비밀번호를 입력하고 로그인한다.

- http://localhost:8090/pro13/login.jsp

5. ID를 입력하면 정상적인 메시지를 출력한다.

6. 하지만 ID를 입력하지 않고 로그인을 시도하면 로그인창으로 포워딩하여 다음과 같은 메시지를 출력한다.

* 그런데 이 로그인 예제는 약간의 문제가 있다. 최초 login.jsp로 접속하면 로그인창에 오류 메시지("아이디를 입력하지 않았습니다. 아이디를 입력해 주세요")가 나타난다는 것이다. 페이지에 처음 접속했을 때는 ID와 비밀번호 입력창만 나타나게 하고, 오류 시에만 오류 메시지를 나타나게 하는 것이 사용자 편의성이 좋다.

* 이 과정을 <jsp:forward> 태그 안에 param 액션 태그를 이용해서 처리해 보자.

7. login2.jsp와 result2.jsp 파일을 새로 만든다.

8. login.jsp를 다음과 같이 작성한다. 로그인창에 접속 시에는 getParameter() 메서드를 이용해 msg 값을 가져와서 표시하도록 구현한다. 최초 요청 시에는 msg값이 null이므로 아무 것도 표시하지 않는다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
   request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>로그인창</title>
    </head>

    <body>
        <%
      		String msg = request.getParameter("msg");
        
	        if(msg != null) {
	    %>
        	<h1><%=msg %> </h1>
        <%
	        } // 브라우저 최초 접속 시에는 msg 값을 가져와서 표시하고, 최초 접속 시에는 null이므로 아무것도 표시하지 않는다.
	    %>

        <form action="result2.jsp" method="post">
            아이디: <input type="text" name="userID"><br>
            비밀번호: <input type="password" name="userPw"><br>
            <input type="submit" value="로그인">
            <input type="reset" value="다시입력">
        </form>
    </body>

<html>

9. ID를 입력하지 않았을 경우 다시 로그인창으로 포워딩하면서 이번에는 <jsp:param> 태그를 이용해 msg 값을 전달한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%
   request.setCharacterEncoding("utf-8");
%>

<%!
    String msg = "아이디를 입력하지 않았습니다. 아이디를 입력해 주세요.";
	// login.jsp로 전달할 오류 메시지를 선언한다.
%>
<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>결과창</title>
    </head>

    <body>
        <%
       		String userID = request.getParameter("userID"); // 로그인 시 입력한 이름을 가져온다.
	        if(userID.length()==0){
	    %>
	    
        <jsp:forward page="login2.jsp">
            <jsp:param name="msg" value="<%= msg %>" />
        </jsp:forward>

        <%	
	      	} // 이름을 입력하지 않았을 경우 <jsp:param> 액션 태그를 이용해 오류 메시지를 login.jsp로 전달한다.
	    %>
        <h1>환영합니다. <%=userID %>님!!! </h1>
    </body>

</html>

10. 다음의 주소로 요청한다. 최초 로그인창 접속 시 앞에서와는 달리 어떤 메시지도 나타나지 않는다.

- http://localhost:8090/pro13/login2.jsp

11. ID를 입력하지 않고 로그인하면 로그인창으로 다시 포워딩되면서 오류 메시지가 나타난다.