1. Webwork 구조
1.1 WebWork 구조

1.2 WebWork 작동
- 최초로 request는 Servlet container(Tomcat or Resin)로 들어온다.
- Request는 standard filter chain을 통과한다.
- FilterDispatcher가 호출된다.(SiteMesh같은걸 추가시 옵션으로 ActionContextCleanUp을 추가가능, FilterDispatcher는 web.xml에 설정)
- FilterDispatcher는 ActionMapper를 이용하여 request URL에 매핑될 Action클래스를 찾는다.( url과 매핑될 action들은 xwork.xml에 정의)
- Action클래스를 찾으면, ActionProxy에 모든 작업을 위임한다.
- ActionProxy는 ActionInvocation을 생성한다.
- 적용할 Interceptor가 있다면, Action 전,후로 Interceptor가 차례대로 실행된다.
- Action이 실행된 다음 ( execute()가 실행), 결과값(result)을 얻는다.
- result에 해당하는 데이터를 xwork.xml로부터 찾아와 해당 페이지(jsp or siteMesh or Tiles..)로 이동하게 된다.
2. Interceptor
- 인터셉터는 action이 실행되기 전, 실행된 후, 또는 양쪽 모두에 호출될 수 있다.
- 인터셉터는 Action 클래스와 실행환경에 대해 완전하게 접근 가능한 능력을 가짐으로써, Action 클래스의 메소드를 호출하거나 실행환경에 대해 원하는 작업을 할 수 있다.
3. ServletDispatcher
- ServletDispatcher(FilterDispatcher)는 ActionProxy를 생성하고, execute()를 호출한다
4. ActionProxy

- ActionProxy는 Action의 전,후에 Interceptor처리를 하고, Action이 실행 완료되면 Result를 리턴받는다.
5. Action
- 개발자는 실제 개발할 때 대부분 Actions, Controllers, Commands들을 다룬다. WW2에서 이것들은 Action이라고 불린다.
- Action 두 가지 종류(Field Driven, Model Driven)가 있다.
- Action 클래스를 정의하기 위해서는 ActionSupport 클래스를 상속받던지 Action 인터페이스를 구현해야 한다.
public class RegisterAction extends ActionSupport {
String username, email, firstname, lastname, password;
private User tempUser;
public String getUserName() {
return username;
}
public void setUserName(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return firstname;
}
public void setFirstName(String firstname) {
this.firstname = firstname;
}
public String getLastName() {
return lastname;
}
public void setLastName(String lastname) {
this.lastname = lastname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String execute() throws Exception {
if (hasErrors())
return INPUT;
else
{
tempUser = WebLogSystem.getUserStore().create(this.username,this.password );
tempUser.setFirstName(this.getFirstName());
tempUser.setLastName(this.getLastName());
tempUser.setEmail(this.getEmail());
tempUser.save();
return SUCCESS;
}
}
/**
* Do business logic validation by checking to see if the user entered is
* already in the database.
*/
public void validate()
{
LOG.info("Validating the registration page");
try{
if(WebLogSystem.getUserStore().verify(this.username))
{
this.addFieldError("Username", "Someone already has that name");
}
}
catch(Exception e)
{e.printStackTrace();
}
}
}
6. Results
- Results 는 적당한 View를 결정하는데 쓰인다.
7 OGNL (Object Graphical Navigation Language)
- JSTL이 주로 출력을 위해서 사용되는 것과 달리 Ognl은 출력뿐 아니라 변수 할당과 같은 것을 하기 위해 사용될 수 있다.
- JSTL과 비슷하다
8. 설정 파일 Reiview
8.1 web.xml
<filter>
<filter-name>webwork</filter-name>
<filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
- 모든 url에 대해 webwork의 FilterDispatcher를 타도록 설정
8.2 xwork.xml
<xwork>
<include file="common/xwork-common.xml"/>
<package name="net.agilejava.jspdp.example" extends="net.agilejava">
<action name="auth" class="net.agilejava.actions.AuthAction">
<result name="success">/success.jsp</result>
</action>
...
</package>
</xwork>
8.3 Action
public class AuthAction extends ActionsSupport{
public String execute() throws Exception{
// TODO
return SUCCESS;
}
}
- Action은 execute를 구현하여야 한다.