[struts/framework] 인터셉터 개요 및 사용자 입력값 처리

2022. 2. 23. 23:39비즈니스 탐색/개발

728x90
반응형

• 뷰에 대한 결정을 contoroller에서 한다

 

Struts2에서 Action 구성하는 세가지 방법

-클래스를 상속받지 않고 인터페이스를 구현하지 않은 일반 자바 클래스(POJO)

-com.opensymphony.xwork2.Action 인터페이스를 구현한 클래스

 

-com.opensymphony.xwork2.ActionSupport 클래스를 상속한 클래스

 

 

POJO 클래스 이용

: 순수자바문법만 가지고 액션을 구성하는 것. 

클래스 자체가 간결하고 쉬운 특성이 있으나 단점은 클래스나 변수를 호출할 수 있게끔 하나하나 지정해줘야. 

 

package hello1.action;

public class HelloWorld {

private String name;

private String msg;

 

public String getMsg() {

return msg;

}

public void setName(String name) {

this.name = name;

}

public String execute() throws Exception {

msg = "Hello," + name;

return "success";

}

}

 

 

 

 

 

# Struts2 Action – Action 인터페이스 이용  

com.opensymphony.xwork2.Action인터페이스는 Action이 실행된 후 리턴하는 결과문자열과

execute() 추상메소드를 포함하고 있는 인터페이스인데 Struts2의 Action을 이 인터페이스를 구현하여 작성할 수 있다.

 

public interface Action

{

    public abstract String execute()

        throws Exception;

 

    public static final String SUCCESS = "success";  <표준적으로 가지고 있는 것: 디포트로 모든 기능이 잡혀있는 것 success>

    public static final String NONE = "none";

    public static final String ERROR = "error";

    public static final String INPUT = "input";

    public static final String LOGIN = "login";

 

}

 

 

 

Struts2 Action – ActionSupport 클래스 상속  

Struts2의 기능을 최대한 활용하기 위해서는 com.opensymphony.xwork2.ActionSupport클래스를 상속받아 Action을 만드는 것이 좋다.

이 클래스는 다음과 같은 인터페이스를 구현한 클래스 이기 때문이다.  

 

com.opensymphony.xwork2.Action

com.opensymphony.xwork2.Validateable

com.opensymphony.xwork2.ValidationAware

com.opensymphony.xwork2.TextProvider 

* 프로바이더: 저장소! 데이터베이스보다는 의미적으로 규모가 축소된 것. ex-핸드폰: 문자저장/ 게임데이터저장 등

* 프로바이더에서 많이쓰는 것: sql light base

com.opensymphony.xwork2.LocaleProvider

 

 

 

 # Validateable 인터페이스

*요청 - struts.xml - excute()동작 - 다시 struts에서 실행되어  result되는 구조에서 excute메서드 보다 먼저 또는 이후에 동작되는 것 전부다 인터셉터.

*set, get 다 인터셉터.

*validate는 set 메서드 다음에 동작한다. 순서로 보면 set 메서드 -   validate메서드 - excute메서드 라고 할 수 있다.

 

 

#유효성 검사

사용자가 요청 파라미터로 넘기는 값에 대해 validation check를 진행 할 validate()메소드를 정의하고 있다.

package com.opensymphony.xwork2;

public interface Validateable

{

    public abstract void validate();

}

 

 

<스트럿츠 에러메시지 화면에 띄어주는 것. 사실상 현재 쓰지는 않는다!!>

쓰지않는 이유: 실제 화면상에서 자기공간을 차지하고있어 실제 화면이 비어보여 붕 떠보이는 단점때문에 잘 쓰지않는다. 

 

package com.opensymphony.xwork2;

 

import java.util.Collection;

import java.util.Map;

 

public interface ValidationAware

{

    //액션 레벨 에러 메시지 Collection을 셋팅

    public abstract void setActionErrors(Collection collection);

 

    //액션 레벨 에러 메시지 Collection을 가져온다.

    public abstract Collection getActionErrors();

 

    // 액션 레벨 일반 메시지 Collection을 셋팅

    public abstract void setActionMessages(Collection collection);

 

    // 액션 레벨 일반 메시지 Collection을 가져온다.

    public abstract Collection getActionMessages();

 

    //필드에러 맵을 셋팅

    public abstract void setFieldErrors(Map map);

 

    //필드에러 맵을 가져온다.

    public abstract Map getFieldErrors();

 

    //현재 액션에 액션 레벨 에러 메시지를 추가

    public abstract void addActionError(String s);

 

    //현재 액션에 액션 레벨 일반 메시지를 추가

    public abstract void addActionMessage(String s);

 

    //현재 액션에 지정한 필드에 대한 에러 메시지를 추가

    public abstract void addFieldError(String s, String s1);

 

    //현재 액션에 액션 에러 메시지가 있는지 검사

    public abstract boolean hasActionErrors();

 

    //현재 액션에 액션 일반 메시지가 있는지 검사

    public abstract boolean hasActionMessages();

 

    //액션에러 또는 필드에러가 있는지 검사

    public abstract boolean hasErrors();

 

    //필드에러가 있는지 검사

    public abstract boolean hasFieldErrors();

}

 

 

 

#인터셉터 기본 동작구조 이해 및 예시

-인터셉터 기본설명

 

Interceptor 사용자의 요청이 Action 도달하기 전에 가로  Action 실행  후에 다른 실행 코드를 넣을  있는 객체이며 어떤 경우 Action 실행되지 않을  있게도 한다.

 어떤 Action 설정된 Interceptor  Action 전처리후처리를 하기 위해 한개의 인스턴스가 존재하여 생성되어 항상  있어 요청이 실행되면 새로운 Action인스턴스가 생성되어

 인터셉터를 통과한다고 보면 된다따라서 인터셉터는 상태가 없는 것이다.

 

인터셉터 여러개의 세트를 Interceptor Stack이라 하는데 특별히 스택이라 부르는 이유는 인터셉터 3개를 넣는다고 하면 먼저 인터셉터1 들어가고 인터셉터2, 인터셉터3 차례로 스택에 들어간다그리고 마지막으로 Action 실행되고 후처리에서는 반대로 인터셉터3, 인터셉터2, 인터셉터1 실행되어 나온다.

 

아래 HelloAction.java에서 set 동작, validate동작, excute동작 순을 보여지도록 작성하면, 어쨌든 다시 form.jsp에서 실행하면  콘솔창에서 set 동작 / validate 동작 / execute  동작을 확인할 수 있다.

 

ⓒjangseonmi
ⓒjangseonmi

 

structs에 <interceptor-ref name="params"/>를 넣고 실행시켜보자. 다시 form.jsp에서 실행하면 - 콘솔창에서 validate가 출력되지 않고 set과 execute만 동작하는 것을 알 수 있다.

 

ⓒjangseonmi

 

다시 form.jsp에서 실행하면 - 콘솔창에서 validate가 출력되지 않고 set과 execute만 동작하는 것을 알 수 있다.

 

ⓒjangseonmi

 

인터셉터를 쓰지않을 경우 액션에 정의된 인터셉터가 다 돌아가는 것이다. 

하지만 위처럼 

<interceptor-ref name="prepare"/> 입력해놓을 시 정의된 것만 동작하는 것을 확인할 수 있다. 

★ 한 마디로, 어떤 인터셉터를 정의하냐에 따라 동작하는 게 달라진다는 점!! 

 

 

 

#DTO 생성해보자.

test.action 패키지에 DTO.java 클래스 생성 - 

이전까지는 폼에서 액션으로 바로 가는 형태였으면 DTO를 통해 현재는 분리시킨 것을 알 수 있다. 폼에서 전달받는 아이디와 패스워드를 바로 DTO에 집어넣는다. (액션클랙스에 get메서드를 사용)

 

ⓒjangseonmi
ⓒjangseonmi

 

 

#인터셉터 동작을 직접 만들어보자.

먼저 패키지 test.interceptor 생성 - MyInterceptor 클래스 생성하고

 

<interceptors>

<interceptor name="my" class="test.interceptor.MyInterceptor"/>

</interceptors>

 

<action name="formPro" class="test.action.HelloAction">

<interceptor-ref name="my" />

</action>

 

 

아래처럼 위 코드를 추가한 컨트롤러로,  structs.xml을 다시 수정하자.

 

★ 여기서 중요한 것은, 인터셉터 사용시 순서있다는 점을 알아둬야한다. 

 <interceptor-ref name="prepare"/>

<interceptor-ref name="modelDriven"/>

<interceptor-ref name="params"/>

위 코드의 순으로 간단히 설명해보면 

prepare로 객체를 생성하고, modelDriven으로 객체를 주고, params로 파라미터로 넣는 것을 알 수 있다. 

 

modelDriven 인터셉터는 ModelDriven 인터페이스를 구현한 액션에서 getModel() 메소드를 실행해서 리턴받은 모델 오브젝트를 ValueStack의 최 상단에 올린다. (액션 보다 위에...)

  따라서 modelDriven 인터셉터를 먼저 붙이고 params 인터셉터를 붙이면 요청파라미터들은 모델 오브젝트의 프로퍼티로 세팅 되는 것이다.

 

prepare 인터셉터는 Preparable  인터페이스를 구현한 액션에서 prepare() 메소드를 호출한다.

  모델 오브젝트를 초기화 하기 위해 되는 것으로 항상 modelDriven 인터셉터보다 먼저 붙여야 한다.

 

 

다시 아래 form.jsp에서 실행해보면 아래처럼 콘솔창에서 init동작 / 인터셉터동작만 나오는 것을 확인할 수 있다.

 

ⓒjangseonmi

컨트롤러에서 <interceptor-ref name="my" /> <interceptor-ref name="prepare"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="params"/>

입력 후 실행하였는데 콘솔창에서는 my만 동작하는 것을 볼 수 있는데, 

 

나머지 3개가 동작하지 않는 이유 - 

각 지점마다 다음으로 넘어가겠다는 동작을 해줘야하는데 현재 작업에서 연결동작값을 넣어주지 않아 3개가 출력되지 않은것을 볼 수 있다.

 

(중요) 연결동작해주는 방법을 바로 알아보자.

★ init

 

 

 

MyInterceptor.java 에 public void init() { System.out.println("init 동작"); } 을 추가.

그리고 오버라이딩 부분에서 return null;값이 아닌, return arg0.invoke(); 로 수정한다.

 invoke메서드 : 현재흐름을 계속 다음으로 이어가는 중요한 메서드로 인터셉터에서는 인보크 매서드가 핵심이라고 볼 수 있다.

 

 

 

음. 사실. 어렵다. 흠.

728x90
반응형