Dev/Struts

Struts2 - Interceptor와 Chain

창문닦이 2019. 3. 26. 11:58

Interceptor 

1. TimerIntercepter 클래스 생성(AbstractInterceptor 추상클래스를 상속)

package com.inter;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

//Intercepter는 filter와 같은 효과를 지닌다.

//인터셉터가 여러개면 순서대로 실행되고 Action을 실행한다.

//모든 Action에 적용할수도있고 부분적으로 Action에 적용 가능

public class TimerIntercepter extends AbstractInterceptor {

private static final long serialVersionUID = 1L;

//로그를 기록할수있도록 로그처리

private static Log log = LogFactory.getLog(TimerIntercepter.class);

@Override

public String intercept(ActionInvocation invocation) throws Exception {

//인터셉터 실행전

long start = System.currentTimeMillis();//시간측정

//Action실행

String result = invocation.invoke();

//인터셉터 실행후

long end = System.currentTimeMillis();//시간측정

//출력

log.info("실행시간:" + (end-start)+"ms");

System.out.println("실행시간: "+ (end-start)+"ms");

return result;//Action의 반환 값(SUCCESS, INPUT)

}

}

2.  wirte페이지

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%

request.setCharacterEncoding("UTF-8");

String cp = request.getContextPath();

%>

<!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=UTF-8">

<title>작성</title>

</head>

<body>

<form action="<%=cp%>/interTest/save.action" method="post">

아이디:<input type="text" name="userName"/><br>

패스워드: <input type="text" name="userPwd"/><br>

<input type="submit" value="전송"/>

</form>

</body>

</html>

3. view페이지

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%

request.setCharacterEncoding("UTF-8");

String cp = request.getContextPath();

%>

<!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=UTF-8">

<title>출력</title>

</head>

<body>

${userName } : ${userPwd }

</body>

</html>

4. Action클래스 생성

package com.inter;

import com.opensymphony.xwork2.ActionSupport;

public class TestAction extends ActionSupport{

private static final long serialVersionUID = 1L;

//DTO

private String userName;

private String userPwd;

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getUserPwd() {

return userPwd;

}

public void setUserPwd(String userPwd) {

this.userPwd = userPwd;

}

@Override

public String execute() throws Exception {

//작업코딩

//반환값

return SUCCESS;

}

}

5. struts-inter.xml 생성

struts2에서 전달하는 매개변수의 이름을 params로 사용하고 있다.
내부적인 문법으로 이 params자체가 인터셉터에 해당되도록 코딩이 되어있다 
내가 만든 인터셉터가 없을때는 내부변수(params)가 자동으로 전달되지만 추가했을 경우는 내부적으로 사용된 변수(params)를 기록해줘야한다.
매번 리퍼런스를 기재하는 것 보다 인터셉터를 하나의 이름으로 묶어 한번에 기재. 하나의 이름으로 그룹을 묶은 것을 Stack이라고 한다. 

<?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="inter" extends="struts-default" namespace="/interTest" >       

<interceptors>

<interceptor name="myTimer" class="com.inter.TimerIntercepter"></interceptor>

</interceptors>

<action name="write">

<result>/inter/write.jsp</result>

</action>

<action name="save" class="com.inter.TestAction">

<interceptor-ref name="myTimer"/>

<interceptor-ref name="params"/>

<result name="success">/inter/view.jsp</result>

</action>


</package>

</struts>

6. struts-config.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>

 <!-- Configuration for the default package. -->

  <package name="default" extends="struts-default" namespace="" >       

      <global-results>

          <result name="error">/exception/error.jsp</result>

      </global-results>

 </package>

 <include file="struts-test.xml"/>

 <include file="struts-board.xml"/>

 <include file="struts-inter.xml"/>

</struts>

7. 콘솔창 확인

인터셉터가 실행되어 콘솔에 실행시간이 찍히는 모습을 볼 수 있다.




CHAIN

하나의 작업이 이뤄지면서 바로 뒤에 다른 작업이 이어지게 되도록 chain을 만들고자함 (회원 가입이 되면서 바로 로그인이 되도록)

1. UserDTO 클래스 생성  

package com.chain;

//Chain

//회원가입과 동시에 로그인 작업

public class UserDTO {

private String userId;

private String userPwd;

private String userName;

private String mode;

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public String getUserPwd() {

return userPwd;

}

public void setUserPwd(String userPwd) {

this.userPwd = userPwd;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getMode() {

return mode;

}

public void setMode(String mode) {

this.mode = mode;

}

}

2. 회원가입용 Action클래스 생성

DTO를 가져와야하기 때문에 impl 해줘야 함

package com.chain;

import com.opensymphony.xwork2.ActionSupport;

import com.opensymphony.xwork2.ModelDriven;

import com.opensymphony.xwork2.Preparable;

public class RegisterAction extends ActionSupport

implements Preparable, ModelDriven<UserDTO>{

private static final long serialVersionUID = 1L;

private UserDTO dto;

private String message;

//requset.setAttribute를 쓰지않아도 dto를 전달해준다.

//Struts2의 기본셋팅 getDto(), getModel(), prepare()

public UserDTO getDto() {

return dto;

}

public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

@Override

public UserDTO getModel() {

return dto;

}

@Override

public void prepare() throws Exception {

dto = new UserDTO();

}

public String created() throws Exception{

if(dto==null||dto.getMode()==null||dto.getMode().equals("")){

return INPUT;

}

setMessage(dto.getUserId() + " 회원 가입 성공!!");

return SUCCESS;

}

}

3. 로그인용 Action클래스 생성

DTO를 가져와야하기 때문에 impl 해줘야 함

package com.chain;

import com.opensymphony.xwork2.ActionSupport;

import com.opensymphony.xwork2.ModelDriven;

import com.opensymphony.xwork2.Preparable;

public class LoginAction extends ActionSupport

implements Preparable, ModelDriven<UserDTO>{

private static final long serialVersionUID = 1L;

private UserDTO dto;

private String message;

//requset.setAttribute를 쓰지않아도 dto를 전달해준다.

//Struts2의 기본셋팅 getDto(), getModel(), prepare()

public UserDTO getDto() {

return dto;

}

public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

@Override

public UserDTO getModel() {

return dto;

}

@Override

public void prepare() throws Exception {

dto = new UserDTO();

}

public String login() throws Exception{

if(dto==null||dto.getMode()==null||dto.getMode().equals("")){

return INPUT;

}

setMessage(dto.getUserId() + " 로그인 성공!!");

return SUCCESS;

}

}

4. 회원가입 register.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%

request.setCharacterEncoding("UTF-8");

String cp = request.getContextPath();

%>

<!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=UTF-8">

<title>회원가입</title>

</head>

<body>

<form action="<%=cp%>/chainTest/created.action" method="post">

이름: <input type="text" name="userName"><br/>

아이디: <input type="text" name="userId"><br/>

패스워드: <input type="text" name="userPwd"><br/>

<input type="hidden" name="mode" value="save"/>

<input type="submit" value="전송"/>

</form>

</body>

</html>

5. 로그인페이지 login.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%

request.setCharacterEncoding("UTF-8");

String cp = request.getContextPath();

%>

<!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=UTF-8">

<title>로그인</title>

</head>

<body>

<form action="<%=cp%>/chainTest/login.action" method="post">

아이디 : <input type="text" name="userId"/><br/>

패스워드 : <input type="text" name="userPwd"/><br/>

<input type="hidden" name="mode" value="login"/>

<input type="submit" value="전송"/><br/>

</form>

</body>

</html>

6. 출력 페이지 result.jsp

<%@ page contentType="text/html; charset=UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%

request.setCharacterEncoding("UTF-8");

String cp = request.getContextPath();

%>

<!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=UTF-8">

<title>결과메세지</title>

</head>

<body>

<h3>${message }</h3>

</body>

</html>


7. struts-chain.xml 생성(Chain설정 하지 않을 경우)

<?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="chain" extends="struts-default" namespace="/chainTest" >       

<action name="created" method="created" class="com.chain.RegisterAction">

<result name="input">/chain/register.jsp</result>

<result name="success">/chain/result.jsp</result>

</action>

<action name="login" method="login" class="com.chain.LoginAction">

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

<result name="success">/chain/result.jsp</result>

</action>

</package>

</struts>

8. struts.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>

 <!-- Configuration for the default package. -->

  <package name="default" extends="struts-default" namespace="" >       

      <global-results>

          <result name="error">/exception/error.jsp</result>

      </global-results>

 </package>

 <include file="struts-test.xml"/>

 <include file="struts-board.xml"/>

 <include file="struts-inter.xml"/>

 <include file="struts-chain.xml"/>

</struts>

★ struts-chain.xml - chain 반영하기

<?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="chain" extends="struts-default" namespace="/chainTest" >       

<action name="created" method="created" class="com.chain.RegisterAction">

<result name="input">/chain/register.jsp</result>

chain을 사용할 경우 내부변수들을 기재하여 전달해야함. 객체가 생성되어 담긴후 전송이 되는 것이므로 이 순서는 바뀌면 오류!

<interceptor-ref name="prepare"/> dto의 객체생성. 담음

<interceptor-ref name="modelDriven"/> dto 전송

<interceptor-ref name="params"/> 내부변수

<result name="success" type="chain">

찾아가야하는 action의 name을 설정

<param name="actionName">login</param>

어느 패키지에 포함되는지도 필요

namespace가 chain2에 있는 액션이라면 chain2로 기재   

<param name="namespace">/chainTest</param>

</result>

</action>

<action name="login" method="login" class="com.chain.LoginAction">

데이터를 받는 Action에서도 chain을 사용할 경우 내부변수들을 기재

<interceptor-ref name="chain"/>

<interceptor-ref name="prepare"/> dto의 객체생성. 담음

<interceptor-ref name="modelDriven"/> dto 전송

<interceptor-ref name="params"/> 내부변수

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

<result name="success">/chain/result.jsp</result>

</action>

</package>

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

///액션 기재////

</package>

</struts>