개발자의 길

Struts2 Interceptor(인터셉터) 2. 본문

5. Jsp

Struts2 Interceptor(인터셉터) 2.

자르르 2010. 1. 20. 13:50


■ Interceptor의 종류



■ Checkbox Interceptor, Parameters Interceptor.

체크되지 않는 값을 다 막아내고 그 값을 출력하더라고 비어있기 때문에 빼버린다.

- checkbox.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "
http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <package name="interCheckbox" namespace="/checkbox" extends="struts-default">
   <!-- 자신이 만든 interceptor은 action 밖에서 사용하고, 존재하는 interceptor의 사용은 action에서 사용한다 -->
   
      <action name="index"
              class="person.actions.IndexAction">
        <result>/person/write.jsp</result>
      </action>
   
      <action name="write"
              class="person.actions.WriteAction">
         
          <param name="name">홍길동</param>
          <interceptor-ref name="staticParams"/> <!-- param을 가질 수 없기 때문에 위로 뺀다. -->
                          
<!-- Checkbox Interceptor 부분 -->
             <interceptor-ref name="checkbox">
              <param name="uncheckedValue">false</param>
<!-- uncheckedValue 예약어다. 체크하지 않은 값은 오지 않는다.-->            
             </interceptor-ref>
             <interceptor-ref name="prepare"/> <!--세개를 써주는게 좋다. default라서 안써도 되지만.-->
             <interceptor-ref name="modelDriven"/>
             <interceptor-ref name="params"/>
         <result>/person/result.jsp</result>
      </action>
     
   </package>

- WriteAction.java

package person.actions;

import person.model.PersonVO;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.interceptor.ParameterNameAware; //특정 파라메터의 값을 받지 않을 경우
import com.opensymphony.xwork2.interceptor.NoParameters; //Interface NoParameters클라이언트가 보내주는 파라미터를 다 차단하겠다.

@SuppressWarnings("unchecked")
public class WriteAction implements Action,
         Preparable,
         ModelDriven,
         ParameterNameAware //Parameters Interceptor 부분 : 특정 파라미터를 안받을 경우
         //NoParameters //Parameters Interceptor 부분 : 모든 파라미터를 안받을 경우
         {
 private String name;
 private PersonVO vo;
 
 //비즈니스 로직 수행 부분
 @Override
 public String execute()throws Exception { //Ation은 execute 메소드를 가지고 있다
  //business logic
  return SUCCESS;
 }
 
 //폼 요청이 들어오면 파라메터의 값을 받기 위해 객체를 생성하고, 각 파라메터의 값을 프로퍼티에 저장한다.
 @Override
 public void prepare() { //preparable, 객체의 초기와 생성
  vo = new PersonVO();
    }

 //execute 메소드를 수행하고 결과를 Result로 전달하는 부분
 @Override
    public Object getModel() { //ModelDriven 데이타를 result로 객체를 넘기는 역할
  return vo;
    }

 //특정 파라메터를 받지 않기 위해 설정한다.
// @Override
 public boolean acceptableParameterName(String parameterName) {
  
  if("name".equals(parameterName)){ //name과 같은 property가 넘어오면 값을 받지 않겠다.
   return false;
  }

  
  return true;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}

- 결과 보기

테이터를 입력 한다.


ParameterNameAware 을 사용하여 name 을 받지 않은 경우.


NoParameters 를 사용하여 모든 데이터를 받지 않은 경우.


■ Exception Interceptor.

- upload.xml

 exception 에는 알 수없는 action에서 error가 발생했을 때 잡는 global exception과, 특정 action에서 error가 발생했을 잡아주는 local Interceptor exception이 있다.

<?xml version="1.0" encoding="euc-kr"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

    <package name="upload" namespace="/upload" extends="struts-default">
     
  <!-- 알 수 없는 action에서 error가 발생 했을 경우 global exception을 발생한다. -->
     <!-- global exception은 action 위에서 는다. -->

    <global-results>
          <result name="exception">/exception/exception.jsp</result>
    </global-results>
     
     <global-exception-mappings> <!-- 여기서 exception이 발생하면 result name의 exception을 요구하고 위의 name 이 exception 인 result 페이지로 이동한다 -->
      <exception-mapping result="exception" exception="java.lang.Exception"/> <!-- exception 잡을 때 최상위를 잡는게 좋다 -->
     </global-exception-mappings>
     
     <action name="index" class="com.myhome.upload.actions.UploadIndexAction">
                  <result>/WEB-INF/upload/register.jsp</result>
     </action>
     
     <action name="register"
       class="com.myhome.upload.actions.UploadMultiAction"
       method="register">

       <!-- local interception exception은 action 안에서 잡는다. -->
      <!-- 특정 액션에서 예외가 발생할 때 인터셉터를 적용한다. -->

      <exception-mapping result="exception" exception="java.lang.NullPointerException"/> <!-- 여기서는 직접 구현한 익셉션을 사용하는게 좋다 -->
      
       <result name="success" type="dispatcher">/WEB-INF/upload/result.jsp</result>
      <result name="input" type="dispatcher">/WEB-INF/upload/register.jsp</result>
      <result name="error" type="dispatcher">/WEB-INF/upload/register.jsp</result>
      <result name="exception">/exception/exception.jsp</result>
     </action>

... 생략 ...

* UploadMultiAction 에 설정해 놓은 NullPointerException 이 발생 할 경우 result name이 exception인 곳으로 데이터를 보내고 exception.jsp에서는 <s:actionerror/>, <s:actionmessage/>, <s:fielderror/>, ${exception.message}, ${exceptionStack} 이런 식으로 데이타를 보여준다.

- exception.jsp

<%@ page contentType="text/html; charset=EUC-KR"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
 <meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
 <title>exception page</title>
  </head>
 
  <body>
 <h2>예기치 않는 오류 발생</h2>
    <p>
              현재 많은 접속자로 인해  시스템의 과부하가 발생하였습니다.
             잠시 후 다시 접속을 시도해 주십시오.
    </p>
    <p>        
             문의사항이 있으시면 admin@myhome.com으로 메일을 보내주십시오.              
    </p>
    <hr/>
     <h3>에러 메시지</h3>
      <s:actionerror/> <!-- action에서 알 수 없는 error 가 걸렸을 때 보기위해 찍는다. -->
      <s:actionmessage/>
      <s:fielderror/>
      <p>
       ${exception.message}
      </p>
    <hr/>
    <h3>에외 상세정보</h3>
    <p>
      ${exceptionStack}
    </p>
 </body>
</html>

- action class

 action class 안에서 다음과 같이 error message 를 추가 할 수 있다.

/*exception handle*/
this.addActionMessage(bean.getName() + " 님이 파일 오류를 발생하였음"); //이렇게 에러 메세지 추가가 가능하다.
throw new NullPointerException("파일을 올려주셈~~");

■ Servlet Config Interceptor


 HtteServletRequest와 HttpServletResponse를 다루는 맵을 엑세스할 수 있게 한다. 

 Servlet-Config Interceptor는 액션들의 Servlet API에서 다양한 객체들을 주입하는 좋은 방법을 제공한다. Struts2는 Servlet API를 제공하지 않기 때문에 servlet 객체에 접근하기 위해 Map을 사용한다. Map의 종류로는 

 ServletContextAware  : ServletContext 객체를 받을 수 있다.

 ServletRequestAware  : HttpServeltRequest 객체를 받을 수 있다.

 ServletResponseAware : HttpServeltResponse 객체를 받을 수 있다.

 ParameterAware       : Parameter Map을 받을 수 있다.

 RequestAware         : Request Map을 받을 수 있다.

 SessionAware         : Session Map을 받을 수 있다.

 ApplicationAware     : Application Map을 받을 수 있다.

맵을 받기 위해서는 각각의 Aware 인터페이스를 구현해야 한다.


- LoginAction.java


package servletConfig.action;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.apache.struts2.interceptor.RequestAware;

import org.apache.struts2.interceptor.ServletRequestAware;

import org.apache.struts2.interceptor.SessionAware;

import servletConfig.dao.LoginDAO;

import servletConfig.interceptor.LoginDAOAware;

import servletConfig.model.UserInfo;

import com.opensymphony.xwork2.Action;

import com.opensymphony.xwork2.ModelDriven;

import com.opensymphony.xwork2.Preparable;


public class LoginAction implements Action, 

                     Preparable, 

     ModelDriven, 

     LoginDAOAware, 

     SessionAware, 

     ServletRequestAware, 

     RequestAware {


    //도메인 오브젝트

    UserInfo userInfo;

    LoginDAO dao;

    Map sessionMap;

    Map requestMap;

    HttpServletRequest request;

    Log log = LogFactory.getLog(LoginAction.class);


    public String execute() throws Exception {

     if (dao.loginChk(userInfo)) {

           sessionMap.put("userInfo", userInfo);

           log.info("----> requestURI : " + request.getRequestURI());

           log.info("----> request ID : " + requestMap.get("id").toString());

           log.info("----> request PWD : " + requestMap.get("pwd").toString());

           return SUCCESS;

        } else {

           return LOGIN;

        }

    }

    

    //Preparable인터페이스의 prepare 구현

    public void prepare() throws Exception {

        userInfo = new UserInfo();

    }

           

    //ModelDriven 인터페이스의 getModel 구현

    public Object getModel() {

        return userInfo;

    }


    //LoginDAUInterceptor에서 LoginDAO를 주입한다.

    public void setLoginDAO(LoginDAO loginDAO) {

        this.dao = loginDAO;

    }


    //SessionAware의 setSession 구현

    public void setSession(Map session) {

        this.sessionMap = session;

    }


    //RequestAware의 setRequest 구현

    public void setRequest(Map requestMap) {

        this.requestMap = requestMap;

    }


    //ServletRequestAware의 serServletRequest 구현

    public void setServletRequest(HttpServletRequest request) {

        this.request = request;

    }


}


- interServletConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

    

<struts>

<package name="interServlet" namespace="/login" extends="struts-default">

<!-- <interceptors>는 자신이 만든 interceptor를 사용하기 위해 정의하는 부분이다. -->

<!-- 더 필요한 정보가 없을 경우 <interceptor-ref name="servletConfig"/> 만 써도 된다. -->

<interceptors>

<interceptor name="loginDao" class="servletConfig.interceptor.LoginDAOInterceptor"/>

</interceptors>

<action name="login" class="servletConfig.action.LoginAction">

<interceptor-ref name="prepare"/>

<interceptor-ref name="modelDriven"/>

<interceptor-ref name="params"/>

<interceptor-ref name="loginDao"/>

<interceptor-ref name="servletConfig"/>

<result>/login/logout.jsp</result>

<result name="login">/login/login.jsp</result>

</action>

<action name="logout" class="servletConfig.action.LogoutAction">

<result>/login/login.jsp</result>

</action>

</package>

</struts>


- LoginDAO.java

package servletConfig.dao;

import servletConfig.model.UserInfo;

public class LoginDAO{

public boolean loginChk(UserInfo userInfo){

//login을 할 때, 아이디를 test로 넣어주어야 홍길동이라는 이름을 보내준다. (test로 넣어주어야 홍길동을 쿼리 해오겠다는 의미)

if("test".equals(userInfo.getId())){

userInfo.setName("홍길동");

return true;

}else{

return false;

}

}

}


- LoginDAOAware.java

package servletConfig.interceptor;

import servletConfig.dao.LoginDAO;

public interface LoginDAOAware{

public void setLoginDAO(LoginDAO loginDAO);

}


- LoginDAOInterceptor.java


package servletConfig.interceptor;

import servletConfig.dao.LoginDAO;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.Interceptor;


@SuppressWarnings("serial")

public class LoginDAOInterceptor implements Interceptor{

LoginDAO loginDAO;

//인터셉터는 라이프 사이클을 가지고 있다.

@Override

public void init() {

loginDAO = new LoginDAO(); //객체 생성

}

@Override

public void destroy() {

loginDAO = null; //객체 소멸

}


//로그인을 셋팅 해주는 과정

@Override

public String intercept(ActionInvocation invocation) throws Exception {

               Object action = invocation.getAction(); //오브젝트로 액션을 얻어 온다.

if(action instanceof LoginDAOAware){ //instanceof는 이게 어느 클래스의 인스턴스인지를 물어볼때 쓰는 키워드이다.

LoginDAOAware loginDAOAware = (LoginDAOAware)action;

loginDAOAware.setLoginDAO(loginDAO);

}

//System.out.println("***************" + invocation.invoke()); //성공시 success를 return 한다.

return invocation.invoke();

}

}


- 실행 모습

http://localhost:8989/Struts2_ServletConfigInterceptor/login/login.action 으로 접속한다.



test라는 아이디를 넣고 로그인을 한다.


그러면 홍길동 이라는 이름으로 로그인 한 모습을 볼 수 있다. LoginDAO.java 에서 test라는 아이디로 들어오면 홍길동이라는 이름을 리턴하게 구현하였기 때문이다. 다른 아이디를 입력 하면 로그인이 되지 않을 것이다.


 



이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공유하기 링크
Comments