View

View 는 클라이언트가 모델의 상태를 보기 위해 사용하는 창(window)이다. 하나의 모델은 여러 창, 즉 뷰를 포함할 수 있으며 클라이언트가 어떤 view를 통해 모델을 보느냐에 따라 화면이 달라진다. 표시 방법으로 XML, XSLT, SOAP, HTML 등 다양한 방법을 택할 수 있으며 Anyframe Web 에서는 주로 자바 코드와 태그로 View를 구성하며 JSP를 기반으로 클라이언트에 동적인 컨텐츠를 제공하게 된다.
View의 역할
  • 사용자 입력 데이터 수용 및 데이터 표시
  • 입력 데이터 검증
  • 에러처리
  • 국제화
자주 사용되는 View 형태
  • HTML : 브라우저를 통해 최종사용자가 보는 페이지이다.
  • JSP Custom Tag : Struts 어플리케이션에서 매우 중요한 역할을 한다, 필수는 아님.
  • JavaScript and StyleSheet : 사용을 금지하지 않으며 적절히 사용하면 효과적인 view를 만들 수 있다.
  • MessageResource Bundle : Localization 기능을 제공하며 유지보수 시간을 절약할 수 있다.
  • Multimedia file

View의 구성요소

JSP 및 관련 기술

JSP

  • 서버에서 동적 웹 컨텐츠를 생성하는 자바 플랫폼 기술, Servlet Container 상에서 수행되는 서버 스크립트 언어
  • 서블릿으로 변환되어 수행되며 최초 요청 시 해당 페이지에 대한 컴파일 된 서블릿 인스턴스는 한번만 생성되므로 서버 자원을 효율적으로 사용
  • 강력한 이식성, 빠른 수행속도, 프리젠테이션 로직과 비즈니스 로직 분리, 컴포넌트의 재사용, 커스텀 태그의 사용으로 인한 개발 편의성 등이 장점

Javascript

  • 넷스케이프에서 만든 인터프리터 형 스크립트 언어
  • 자바스크립트 코드는 HTML 페이지 내에 삽입될 수 있으며, 클라이언트 측인 웹 브라우저에 의해 해석됨
  • 객체 지향 모델로써 구조화된 문서를 표현하는 표준 형식인 DOM(Document Object Model) 객체를 다루고 프로그램으로 조작(manipulate)함

CSS

  • Cascading Style Sheet는 마크업 언어(HTML, XHTML, XML)가 실제 표시되는 방법을 기술하는 언어로 W3C의 표준임
  • 스타일 정보의 수정 시 홈페이지 전체에서 이에 해당하는 요소들이 한꺼번에 반영됨
  • 각기 다른 사용자 환경에서도 동일한 형태의 문서를 제공

DHTML : 정적 마크업 언어인 HTML, 클라이언트 기반 스크립트 언어(ex. Javascript)와 스타일 정의 언어인 CSS를 조합하여 대화형 웹 사이트를 제작하는 기법을 의미함

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

  1. 액션의 매핑 정보를 확인하고 ActionForm이 설정되어 있는지 검사한다.
  2. 액션에 ActionForm이 설정되어 있다면, 폼 빈의 설정 정보에서 action요소의 name속성을 찾는데 사용한다.
  3. 이미 만든 ActionForm 인스턴스가 있는지 검사한다.
  4. ActionForm 인스턴스가 적합한 scope에 있고 요청에 필요한 타입과 같다면 재사용한다.
  5. ActionForm 인스턴스가 적합한 scope내에 없다면 새로운 인스턴스를 만들고 action 요소의 scope 속성에 따른 scope에 저장한다.
  6. ActionForm 인스턴스의 reset() 메소드를 호출한다.
  7. 요청 파라미터의 이름에 따른 ActionForm의 setter 메소드를 통해서 요청 파라미터의 값을 ActionForm에 입력한다. (populate 라고 한다.)
  8. 마지막으로 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>

Resources