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 { //Action은 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라는 아이디로 들어오면 홍길동이라는 이름을 리턴하게 구현하였기 때문이다. 다른 아이디를 입력 하면 로그인이 되지 않을 것이다.
자세한 내용은 파일을 참조 한다.
클라이언트가 보내는 파라미터를 무시하고 미리 설정해 놓은 파라미터로 값을 넣는다.
struts.xml에 정의된 파라미터 값들을 액션에저장한다. <action> 태그 의 직속 자식으로<param> 태그가 있다.
- xml 파일에 아래와 같이 태그를 추가한다.
<param name="name">홍길동</param>
<interceptor-ref name="staticParams"/>
- action class 에서
param 네임으로 getter, setter를 생성한다.
■ Timer Interceptor
인터셉터와 뷰 처리를 포함하여 액션의 작업 처리 시간을 출력한다.
- xml 파일 안에 아래와 같이 추가
<interceptor-ref name="timer"/> <!-- 작업시간에 대한 결과를 출력한다. -->
이렇게 추가해 주고 실행하면 작업 시간이 콘솔 창이 나타난다.