액션 태그란 JSP에서 객체 생성과 공유, 페이지 이동과 전달, 태그 파일 작성 등에 필요한 기능을 제공하는 일종의 커스텀 태그다. 표준 액션이라고도 불리며 커스텀 태그 기반이지만 별도의 taglib 지시어 사용 없이 jsp 접두어를 사용한다.
액션 태그는 JSP에서 프로그램적인 요소를 많이 구현하거나 컨트롤러로 활용할 때 유용하다. 이러한 기능은 기본적으로 서블릿에서도 가능하지만 개발자가 직접 코들르 구현하여 처리해야 한다. 반면 액션 태그는 JSP 파일에서 커스텀 태그의 구조적인 특징을 살려 HTML 형태로 프로그램 요소를 처리할 수 있기 때문에 간편하다는 장점이 있다.
요즘은 JSP의 역할이 축소되어 있어 액션 태그의 실무 활용은 권장되지 않아 간략히 살펴본다.
액션 태그 | 설명 |
---|---|
jsp:forward | request와 response 객체를 포함해 다른 페이지로 포워드함 |
jsp:include | 다른 페이지의 실행 결과를 포함시킴 |
jsp:useBeans | 자바 빈즈 객체를 생성하거나 불러옴 |
jsp:setProperty | 자바 빈즈 객체의 속성에 값을 할당함 |
jsp:getProperty | 자바 빈즈 객체의 속성값을 출력함 |
jsp:param | include, forward 액션 사용 시 파라메터 값을 수정하거나 추가함 |
객체지향 프로그래밍의 핵심 콘셉트는 컴포넌트 모델로, 프로그램 모듈화를 위해 컴포넌트를 사용한다. 따라서 컨테이너 기반으로 운영되는 시스템에서는 여러 객체를 활용하기 위하여 단순하면서도 정영화된 구조를 통해 동일한 방식으로 객체를 다루는 방법을 제공할 수 있어야 한다.
자바 빈은 자바의 재활용 가능한 컴포넌트 모델을 말하는 것으로, 웹 개발에만 국한된 개념이 아니며 POJO라고 하는 단순한 구조를 가진다. POJO란 특정 기술이나 프레임워크에 종속하지 아니하고 기본 생성자와 멤버 변수에 대한 getter setter 메서드를 제공하고 직렬화 할 수 있는 자바 클래스를 의미한다.
예를 들어 데이터베이스의 테이블 구조와 연동되어 데이터를 표현하기 위한 클래스를 엔티티 클래스 혹은 DO라고 하는데 기본적으로 테이블 칼럼에 해당하는 private 멤버 변수와 getter setter 메서드로 구성할 수 있다.
자바 빈 구조는 다음과 같다.
다음은 회원 관리를 위한 Member 클래스를 자바 빈 구조로 만든 것이다.
public class MemberBean {
private String id;
private String password;
private String email;
private int age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
getter/setter 메서드의 이름은 get/set + 대문자로 시작되는 변수명의 형태를 사용한다. 기본적으로 인자를 받아 현재 멤버 변수에 값을 대입하거나 현재 값을 리턴하는 구조이다. 메서드 내에서 추가적으로 필요한 기능을 구현할 수 있으며 이러한 구조는 객체지향에서 캡슐화의 한 형태
이기도 하다.
스프링 빈이란 스프링 프레임워크의 경우에도 컨테이너 기반으로 객체의 생성과 소멸 등을 관리하게 되는데 이러한 객체를 스프링 빈이라고 한다. 이러한 객체는 컨테이너를 통해 공유하거나 참조할 수 있다.
JSP에서 자바 빈 객체를 생성하거나 참조하기 위한 액션이다. 매우 유용한 기능이지만 JSP를 단순히 뷰 역할로만 사용한다면 사용할 일이 없다.
기본적인 동작 방식은 다음과 같다.
기본 구문과 사용 예는 다음과 같다.
<jsp:useBean id="instanceName" scope="page | request | session | application"
class="packageName.className" type="packageName.className"
beanName="packageName.className">
</jsp:useBean>
HTML 폼에서 입력한 값을 자바 객체로 연동할 때 useBean을 주로 활용한다. 예를 들어 회원가입 페이지에서 아이디, 이름, 전화번호, 주소 등 여러 정보를 입력하고 가입하는 경우, 입력값을 받아 Member 객체에 넣고 이를 데이터베이스에 저장하기 위한 메서드 호출에 인자로 전달해야 한다.
이 때 useBean 액션을 사용하면 다음 코드와 같이 간단한 처리가 가능하다.
<jsp:useBean id="m" class="com.my.Member" />
<jsp:setProperty name="m" property="*" />
<%
MemberDao dao = new MemberDao();
dao.insertDb(m);
%>
<form>
태그의 name 속성값을 해당 객체의 setter 메서드를 이용해 저장한다.*
을 사용해 전체 변수를 한 번에 지정할 수 있다.include 액션은 include 지시어와 마찬가지로 다른 페이지를 포함한다는 점에서 동일하지만 처리 과정에서 차이가 있다. include 지시어에서는 include된 파일 구조를 모두 포함해 하나의 파일로 컴파일한 다음 처리한다. 반면 include 액션은 include된 파일을 각각 호출해 처리된 결과만 포함해 보여주는 형식이다.
만약 main.jsp
에서 header.jsp
를 포함한다고 할 때 include 지시어는 두 파일을 합쳐 main_jsp.java
로 만든 다음 서블릿 형태로 등록한다. 하지만 include 액션의 경우 main_jsp.java
와 header_jsp.java
의 두 파일을 각각 컴파일하고 서블릿 형태로 등록하게 된다.
다음 예제 코드는 include 액션을 사용하여 main.jsp
에 header.jsp
를 포함시킨 경우로, main.jsp
를 호출하면 header.jsp
의 실행 결과가 포함되어 출력된다.
<!-- main.jsp -->
<jsp:include page="header.jsp">
<jsp:param name="title" value="My Homepage" />
</jsp:include>
<!-- header.jsp -->
<h2><%= request.getParameter("title") %></h2>
main.jsp
에서 header.jsp
를 include할 때 <jsp:param>
에서 title을 통해 My Homepage라는 값을 전달한다. 그리고 header.jsp
는 <h2>
부분에서 전달받은 제목을 출력하는 형태가 된다.forward 액션은 클라이언트 요청을 다른 페이지로 전환하는 액션으로 리디렉션 response.sendRedirect()
과 기능적으로 유사하다. 클라이언트 요청과 다른 새로운 페이지 혹은 서블릿으로 이동하는 점은 두 방법이 동일하다고 할 수 있지만 내부적으로는 차이가 있다.
리디렉션은 서버가 클라이언트에게 새로운 페이지로 다시 접속하도록 응답을 보내고, 응답을 받은 클라이언트가 다시 새로운 페이지로 접속하는 방식이다. 하지만 forward 액션은 클라이언트가 새롭게 접속하는 것이 아니라 서버에서 내부적으로 새로운 페이지로 이동하고 그 페이지의 내용을 클라이언트에게 응답으로 전달한다.
단순한 페이지 이동이 필요한 경우라면 리디렉션이 적합하다. 하지만 최초 request를 유지하거나 request의 setAttribute()로 속성값을 저장한 경우에 이를 유지하면서 페이지를 이동하려면 forward 액션을 사용해야 한다. include 액션과 마찬가지로 파라미터의 추가가 가능하다.
JSP를 뷰로 사용하는 경우 forward 액션을 사용할 일은 없으며 주로 서블릿 컨트롤러에서 request.getRequestDispatcher.forward()
와 같이 사용하게 된다.