View 는 클라이언트가 모델의 상태를 보기 위해 사용하는 창(window)이다.
하나의 모델은 여러 창, 즉 뷰를 포함할 수 있으며 클라이언트가 어떤 view를 통해 모델을 보느냐에 따라 화면이 달라진다.
표시 방법으로 XML, XSLT, SOAP, HTML 등 다양한 방법을 택할 수 있으며
Anyframe Web 에서는 주로 자바 코드와 태그로 View를 구성하며
JSP를 기반으로 클라이언트에 동적인 컨텐츠를 제공하게 된다.
ActionForm
웹 어플리케이션에서 사용자의 입력을 받을 때 페이지에는 텍스트 박스, 버튼 등과 같은 컴포넌트들이 HTML 의 폼 요소 내에 포함되어 있고
사용자가 버튼을 누르게 되면 필드 내에 있는 값들이 HTTP request와 함께 서버로 submit 된다.
서버 어플리케이션은 request에서 이 입력 값들을 꺼내어 올바른 데이터를 입력했는지 validation을 수행하고 나서 실제 비지니스를 수행하기 위해 Action으로 데이터를 넘기게 된다.
만일 입력 데이터가 validation rule을 통과하지 못한 경우 에러 메시지를 설정하여 입력 페이지로 돌아가게끔 처리해야 한다.
이처럼 요청에서 입력 값을 꺼내어 검증을 수행하고 실패에 대한 에러 메시지를 출력하는 등의 기능을 직접 구현하는 것은 쉬운 일이 아니다.
또한 이런 작업은 전체 어플리케이션 내에서 반복해서 일어나므로 재사용하는 것이 좋다.
이러한 작업들을 해주는 것이 org.apache.struts.action.ActionForm 클래스 이다.
ActionForm의 역할
- 요청에서 입력 값을 꺼내어 검증 수행, 실패에 대한 에러 메시지를 출력하는 등의 일련의 처리 과정을 재사용
- ActionForm은 클라이언트의 입력 값을 Action으로 전달하고, 결과를 되돌려줄 수 있음
- 입력 데이터들을 검증하는 동안 상태를 보관하는 버퍼로 동작
- 확실하지 않은 입력 값들을 검증 룰을 통해 세밀하게 조사하기 전까지 비즈니스 계층 밖에 위치하도록 해주는 firewall 역할
- ActionForm을 화면 표시 데이터로 설정하여 HTML 폼의 입력 필드를 쉽게 표시할 수 있음
Html 입력 Form으로 부터 받은 parameter 들은 자동으로 ActionForm 객체에 채워진다.
검증을 위한 validate() 메소드와 parameter가 ActionForm에 채워지기 전에 초기화 하는 reset() 메소드를 구현해야 한다.
struts-config.xml 에 ActionForm 에 대한 <form-beans> 정의가 필요하다.
ActionForm은 Model의 부분이 아니다. 비즈니스 처리를 수행하기 위한 Model 영역은 Controller / View 와 완전히 분리하여야 하며
직접 비즈니스 계층으로 전달해서는 안되고 ValueObject 나 Parameters 같은 형태의 Data Transfer Object를 생성하여 전달하도록 해야 한다.
ActionForm의 단점
- 어플리케이션 개발자가 ActionForm의 서브클래스를 직접 구현해야 함
- 많은 수의 클래스가 생겨날 수 있어서 유지보수 관리 어려움
- HTML Form 의 변경 시 ActionForm Class 수정 필요
DynaActionForm
- 실제 구현 클래스들을 만들 필요가 없음
- Property는 configuration파일에서 설정
- validate() 메소드를 구현하려면 DynaActionForm을 상속받아 직접 구현해야함. Validator 프레임워크를 이용하는 것이 좋음.
ActionForm의 scope
- ActionForm 객체가 저장되어 유지되는 context의 scope를 나타낸다.
- session, request 2가지 레벨이 있다.
- struts-config.xml 의 <action>의 scope 속성으로 설정한다. default는 session이다. session scope일 경우 ActionForm의 제거에 유의해야 한다.
ActionForm의 LifeCycle
- 액션의 매핑 정보를 확인하고 ActionForm이 설정되어 있는지 검사한다.
- 액션에 ActionForm이 설정되어 있다면, 폼 빈의 설정 정보에서 action요소의 name속성을 찾는데 사용한다.
- 이미 만든 ActionForm 인스턴스가 있는지 검사한다.
- ActionForm 인스턴스가 적합한 scope에 있고 요청에 필요한 타입과 같다면 재사용한다.
- ActionForm 인스턴스가 적합한 scope내에 없다면 새로운 인스턴스를 만들고 action 요소의 scope 속성에 따른 scope에 저장한다.
- ActionForm 인스턴스의 reset() 메소드를 호출한다.
- 요청 파라미터의 이름에 따른 ActionForm의 setter 메소드를 통해서 요청 파라미터의 값을 ActionForm에 입력한다. (populate 라고 한다.)
- 마지막으로 validate 속성이 "true"로 설정되어 있다면 ActionForm 인스턴스의 validate()메소드를 수행하고 검증과정에 에러가 있다면 에러들을 반환한다.
다음은 ActionForm 작성의 예를 보여주는
UserForm.java
의 일부 소스코드이다.
public class UserForm extends ActionForm{
private String userId;
private String password;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void reset(ActionMapping mapping, HttpServletRequest request) {
this.password = null;
this.userId = null;
}
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if ((userId == null) || (userId.length() < 1))
errors.add("userId", new ActionMessage("error.userid.required"));
if ((password == null) || (password.length() < 1))
errors.add("password", new ActionMessage("error.password.required"));
return errors;
}
}
화면에서 입력받을 요소에 대한 attribute를 정의하고 해당 getter/setter 메소드를 작성한다.
또한 검증을 위한 validate 메소드와 초기화를 위한 reset 메소드를 구현해야 한다.
ActionErrors 사용하기
위 ActionForm 소스의 validate 메소드에서 ActionErrors 객체를 반환하는 것을 보았다. 여기서는 ActionErrors의 사용에 대해 알아본다.
- ActionErrors는 어플리케이션에서 발견한 에러를 하나 이상 캡슐화한다.
- request에 저장된 ActionErrors는 이후 JSP 에서 custom tag를 통해 사용자들에게 에러 메시지로 보여진다.
다음은 ActionMessage 생성의 예이다.
ActionMessage message = new ActionMessage("global.error.login.requiredfield", "email");
위의 첫번째 인자는 리소스 번들 내의 키 중 하나와 일치하는 문자열이고, 두번째 인자는 메시지를 위한 parameter이다.
아래는 리소스 번들 내의 관련 메시지 정의이다.
global.error.login.requiredfield=The {0} field is required.
{0} 부분에는 email 이란 글자가 찍혀 표시된다.
위의 형태 외에도 복수개의 메시지 파라메터를 처리할 수 있는 몇가지 생성자 유형이 더 있다.
ActionMessage는 ActionForm의 validate 에서만 생성할 수 있는 것은 아니다.
예를 들어, Action에서 호출한 비즈니스 처리에서 예외가 발생했고 이를 사용자에게 알리기 위한 에러 메시지를 추가하려고
할 때도 ActionMessage를 사용할 수 있다.
JSP 에서 Taglib를 이용해 메세지로 ActionErrors를 보여주는 예는 다음과 같다.
<%@ page contentType="text/html; charset=euc-kr" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<html:html>
<head>
<title>Error Page</title>
</head>
<body>
<html:errors/>
</body>
</html:html>