리절트(result) 설정 개요
Struts2에서 액션 메서드가 실행된 후 어떤 뷰를 반환할지 결정하는 요소가 바로 <result>입니다. 이 설정은 반환 값(name)과 함께 타입(type)에 따라 다양한 방식으로 응답을 처리할 수 있습니다.
주요 result type 종류
- dispatcher: 기본값으로, 서버 내부에서 JSP로 포워딩합니다. 클라이언트 URL은 변경되지 않으며 같은 요청(request) 범위 내에서 데이터 공유가 가능합니다.
- redirect: 클라이언트에게 새 페이지로 리다이렉트하도록 지시합니다. 새로운 요청이 발생하므로 기존 request 스코프의 데이터는 소실됩니다.
- chain: 현재 액션에서 다음 액션으로 제어를 넘깁니다. 두 액션 간에 스택 컨텍스트가 유지되어 데이터를 공유할 수 있으며, URL은 변하지 않습니다.
- redirectAction: 클라이언트를 다른 액션으로 리다이렉트합니다. 새로운 HTTP 요청이 생성되므로 request 데이터는 전달되지 않지만, URL이 변경됩니다.
- freemarker, velocity: 템플릿 엔진을 사용한 렌더링을 위한 타입입니다.
예제 코드 구현
아래는 각 리절트 타입을 테스트하기 위한 액션 클래스와 설정 파일입니다.
Action 클래스 정의
package com.example.action;
import com.opensymphony.xwork2.ActionSupport;
public class GreetingAction extends ActionSupport {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String execute() {
return SUCCESS;
}
// redirect 테스트
public String redirectToPage() {
return "redirect";
}
// chain 테스트
public String chainToNext() {
return "chained";
}
// redirectAction 테스트
public String redirectAction() {
return "redirectAction";
}
}
package com.example.action;
import com.opensymphony.xwork2.ActionSupport;
public class TargetAction extends ActionSupport {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String execute() {
this.message = "처리 완료";
return SUCCESS;
}
}
struts.xml 구성
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<package name="app" namespace="/" extends="struts-default">
<action name="greet" class="com.example.action.GreetingAction">
<result name="success">success.jsp</result>
<result name="redirect" type="redirect">success.jsp</result>
<result name="chained" type="chain">target</result>
<result name="redirectAction" type="redirectAction">target</result>
</action>
<action name="target" class="com.example.action.TargetAction">
<result name="success">success.jsp</result>
</action>
</package>
</struts>
뷰 파일: success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<p>사용자 이름: ${userName}</p>
<p>메시지: ${message}</p>
</body>
</html>
테스트용 인덱스 페이지
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<a href="greet?userName=홍길동" target="_blank">기본 포워딩 (dispatcher)</a><br/>
<a href="greet!redirectToPage?userName=홍길동" target="_blank">리다이렉트 (redirect)</a><br/>
<a href="greet!chainToNext?userName=홍길동" target="_blank">체인 전달 (chain)</a><br/>
<a href="greet!redirectAction?userName=홍길동" target="_blank">액션 리다이렉트 (redirectAction)</a><br/>
</body>
</html>
결과별 동작 분석
- dispatcher: request 속성 유지됨, URL 변경 없음.
- redirect: userName 속성 소실, 새 요청 생성, URL 변경됨.
- chain: userName 포함하여 다음 액션까지 전달됨, URL 유지.
- redirectAction: 클라이언트가 target 액션을 새로 요청하므로 userName 유실, URL 변경됨.
전역 리절트 설정 (Global Results)
여러 액션에서 공통적으로 사용하는 결과 페이지(예: error.jsp)는 중복을 피하기 위해 전역으로 선언할 수 있습니다.
전역 에러 처리 예제
public class GreetingAction extends ActionSupport {
private String userName;
// getter/setter 생략
public String execute() {
if (userName == null || userName.trim().isEmpty()) {
addActionError("사용자 이름은 필수입니다.");
return ERROR;
}
return SUCCESS;
}
}
struts.xml - 전역 리절트 적용
<package name="app" namespace="/" extends="struts-default">
<global-results>
<result name="error">error.jsp</result>
</global-results>
<action name="greet" class="com.example.action.GreetingAction">
<result name="success">success.jsp</result>
<!-- error는 전역에서 처리 -->
</action>
</package>
error.jsp
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:property value="actionMessages"/>
액션 로컬 리절트가 우선하며, 해당 액션에 정의되지 않은 경우 전역 리절트가 참조됩니다.