티스토리 뷰

 

[ 1. 인터셉터 ]

 

[ 1 - 1. 인테셉트 당할 URI 생성 ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.controller;

import java.util.Locale;

import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.zerock.myapp.exception.ControllerException;

import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;


@Log4j2
@NoArgsConstructor

@RequestMapping("/sample/")
@Controller
public class SampleController {
	
	// ==================================================================================
	
	@ResponseStatus(code = HttpStatus.OK)
	@GetMapping("/doA")
	public String doA ( Locale locale, Model model ) throws ControllerException {
		// + Locale locale : Locale은 현재 거주하고 있는 지역을 얻어낼 수 있다.
		log.trace("doA() invoked.");
		
		try {
			
			model.addAttribute("serverTime", "/sample/doA");
			return"home";
			
		} catch (Exception e) {
			throw new ControllerException(e);
		} // try - catch
		
	} // doA
	
	// ==================================================================================
	
	@ResponseStatus(code = HttpStatus.OK)
	@GetMapping("/doB")
	public String doB ( Locale locale, Model model ) throws ControllerException {
		// + Locale locale : Locale은 현재 거주하고 있는 지역을 얻어낼 수 있다.
		log.trace("doB() invoked.");
		
		try {
			
			model.addAttribute("serverTime", "/sample/doB");
			return"home";
			
		} catch (Exception e) {
			throw new ControllerException(e);
		} // try - catch
		
	} // doB
	
	// ==================================================================================
	
	@ResponseStatus(code = HttpStatus.OK)
	@GetMapping("/doC")
	public String doC ( Locale locale, Model model ) throws ControllerException {
		// + Locale locale : Locale은 현재 거주하고 있는 지역을 얻어낼 수 있다.
		log.trace("doC() invoked.");
		
		try {
			
			model.addAttribute("serverTime", "/sample/doC");
			return"home";
			
		} catch (Exception e) {
			throw new ControllerException(e);
		} // try - catch
		
	} // doC
	
	// ==================================================================================
	
	@ResponseStatus(code = HttpStatus.OK)
	@GetMapping("/doD")
	public String doD ( Locale locale, Model model ) throws ControllerException {
		// + Locale locale : Locale은 현재 거주하고 있는 지역을 얻어낼 수 있다.
		log.trace("doD() invoked.");
		
		try {
			
			model.addAttribute("serverTime", "/sample/doD");
			return"home";
			
		} catch (Exception e) {
			throw new ControllerException(e);
		} // try - catch
		
	} // doD
	
	// ==================================================================================

} // end class

 

[ 1 - 2. 인터셉터 생성 ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.interceptor;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.ui.ModelMap;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;


@Log4j2
@NoArgsConstructor

@Component // @Component로 HandlerInterceptor를 빈으로 등록하였다.
public class SampleInterceptor implements HandlerInterceptor {
	// + 인터셉터는 반드시 HandlerInterceptor를 상속받아야 한다. (***)
	
	// =======================================================================================================
	
	// + 1. Dispatcher Servlet이 받은 request를 Controller의 Handler Method로 전달되기 전에 가로챈다.
	// + Servlet-context/xml에서 sample/doA에 들어오는 것을 SampleInterceptor가 가로채도록 되어 있기에,
	// + /sample/doA로 접속을 시도하면, 그 전에 preHandle(req, res, handler) invoked.가 발생한다.
	@Override
	public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler)
			throws Exception {
		
		log.trace("======================================================");
		log.trace("1. preHandle(req, res, handler) invoked.");
		log.trace("======================================================");
		
		log.info("\t + 1. handler : {}", handler);
		// + 1. handler : org.zerock.myapp.controller.SampleController#doB(Locale, Model)
		
		log.info("\t + 2. handler type : {}", handler.getClass().getName());
		// + 2. handler type : org.springframework.web.method.HandlerMethod
		log.trace("\t ======================================================");
		
		HandlerMethod controllerHandler = (HandlerMethod) handler;
		Object controller = controllerHandler.getBean();
		Method method = controllerHandler.getMethod();
		
		log.info("\t + 3. controllerHandler : {}", controllerHandler);		// HandlerMethod 타입의 객체
		// + 3. controllerHandler : org.zerock.myapp.controller.SampleController#doB(Locale, Model)
		
		log.info("\t + 4. controller : {}", controller);					// SampleController 객체
		// + 4. controller : org.zerock.myapp.controller.SampleController@1b6656
		
		log.info("\t + 5. method : {}", method);							// SampleController 안에 있는 메소드
		// + 5. method : 
		// + public java.lang.String org.zerock.myapp.controller.SampleController.doB(java.util.Locale,org.springframework.ui.Model)
		// + throws org.zerock.myapp.exception.ControllerException
		log.trace("\t ======================================================");
		
		String clientAddr = req.getRemoteAddr();
		log.info("\t + clientAddr : {}", clientAddr);
		// + 접속하는 사람의 IP주소를 확인할 수 있다.
		log.trace("\t ======================================================");

		return true; // 기본값이 true로 설정되어 있다.
		// + return은 다음 체인으로 넘길지 말지 지정해 주는 것이다.
		// + true라면, 만약 다음 인터셉트가 있을 경우 다음으로 넘겨주고, 다음이 없다면 뒤의 컨트롤러 메소드를 수행한다.
		// + false라면, 만약 다음 인터셉트가 있을지라도 다음으로 넘겨주지 않는다.
		// + false일 경우에는 컨트롤러 메소드뿐만이 아니라, postHandle()과 afterCompletion()도 수행기키지 않는다!! (***)
		
	} // preHandle
	
	// =======================================================================================================

	// + 2. Controller의 Handler Method가 수행된 직후 ( 단, view가 호출되기 전 )
	// + (*주의*) 단, Controller의 Handler Method에서 예외가 발생하면, 아래의 메소드는 호출되지 못한다.
	@Override
	public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler,
			ModelAndView modelAndView) throws Exception {
		
		log.trace("============================================================");
		log.trace("2. postHandle(req, res, handler, modelAndView) invoked.");
		log.trace("============================================================");
		
		log.info("\t + 1. modelAndView : {}", modelAndView);
		// + 1. modelAndView : ModelAndView [view="home"; model={serverTime=/sample/doA}]
		// + 컨트롤러에서 반환하는 View의 이름과 model을 보여준다.
		
		log.trace("\t ======================================================");
		
		modelAndView.setViewName("redirect:/login");
		ModelMap model = modelAndView.getModelMap();
		model.put("serverTime", "*^^*");
		// + 이렇게 전달된 뷰의 이름이나 model을 수정할 수 있다. (**)
		log.info("\t + 2. update modelAndView : {}", modelAndView);

	} // postHandle
	
	// =======================================================================================================

	// + 3. View까지 호출이 완료되어, request에 대한 response가 전송완료된 직후
	// + (*주의*) 단, Controller의 Handler Method에서 예외가 발생하든 안하든, 무조건 호출된다.
	// + afterCompletion는 응답을 완전히 바꿔버릴 수도 있다.
	@Override
	public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object handler, Exception e)
			throws Exception {
		
		log.trace("======================================================");
		log.trace("3.afterCompletion(req, res, handler, e) invoked.");
		log.trace("======================================================");

	} // afterCompletion
	
	// =======================================================================================================

} // end class

 

[ 1 - 3. 인터셉터를 servlet-context.xml에서 등록 ]

 

더보기

[ + 코드 보기 ]

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

<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- < resources mapping location >의 경우 파일을 생성하여 매핑할 수 있으며, 같은 location이여도 mapping을 추가할 수 있다. -->
	<!-- 아래의 태그로 인해 URL mapping처럼 http://localhost:8080/resources/파일명으로 접근이 가능하다. -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- [ 현재 버전 ] -->
	<!-- View Resolver -->
	<view-resolvers>
		<jsp prefix="/WEB-INF/views/" suffix=".jsp" />
	</view-resolvers>

	<!-- ===================================================================================================== -->

	<!-- 파일 업로드 -->
	<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<beans:property name="defaultEncoding" value="utf8" />
		<!-- 최대 10mb까지 업로드 가능 -->
		<beans:property name="maxInMemorySize" value="10485760" />
		<beans:property name="maxUploadSize" value="10485760" />
		<!-- 파일 1개당 최대 사이즈는 2mb로 제한 -->
		<beans:property name="maxUploadSizePerFile" value="2097152" />
		<!-- 파일의 이름을 저장할지 지정 -->
		<beans:property name="preserveFilename" value="true" />
		<!-- 업로드할 정소 지정 -->
		<!-- 로컬에서는 경로를 file:///로 시작해야 한다. -->
		<!-- multipartResolver 빈에서는 임시폴더를 지정해야 하기에 Temp까지만 지정해 준다. -->
		<beans:property name="uploadTempDir" value="file:///C:/Temp/" />
	</beans:bean>

	<!-- 수동 등록 방법 -->
	<!-- <beans:bean id="sampleInterceptor" class="org.zerock.myapp.interceptior.SampleInterceptor" /> -->

	<!-- ===================================================================================================== -->

	<!-- 인터셉터 등록 방법 (****) -->
	<interceptors>

		<interceptor>
			<!-- + path지정한 URI를 보고 가로채서, bean에서 지정한 인터셉터가 처리한다. (***) -->
			<!-- + path는 여러개 지정이 가능하다. ( 이렇게 되면 sampleInterceptor가 2개의 URI를 인터셉트하게 된다. -->
			<!-- + path="/sample/do*"와 같이 와일드 카드를 사용하여 지정해 줄 수도 있다. -->
			<!-- + *는 뒤에 몇글자가 와도 포함되는 와일드 카드고, ?는 단문자만 포함하는 와일드 카드이다. -->
			<!-- + 같은 path를 인터셉트할 경우에는 필터처럼 체이닝되게 된다.(*) -->
			<mapping path="/sample/doA" />
			<mapping path="/sample/doB" />
			<mapping path="/sample/do*" />
			<beans:ref bean="sampleInterceptor" />
		</interceptor>

		<!-- + 이렇게 등록할 경우 /sample/doB로 접속할때 인터셉터 체인이 형성되어 인터셉터가 2번실행되게 된다. -->
		<interceptor>
			<mapping path="/sample/doB" />
			<beans:ref bean="sampleInterceptor2" />
		</interceptor>

	</interceptors>

	<!-- ===================================================================================================== -->

	<!-- base-package에 작성한 패키지 내에 있는 것을 빈으로 등록시킨다. -->
	<context:component-scan base-package="org.zerock.myapp.controller" />
	<context:component-scan base-package="org.zerock.myapp.exception" />
	<context:component-scan base-package="org.zerock.myapp.interceptor" />

	<!-- ===================================================================================================== -->
	
</beans:beans>

[ 2. 로그인 처리 - 세션 트레킹 ] (*****)

 

[ 2 - 1. 로그인 정보를 받아들일 DTO 생성 ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.domain;

import lombok.Data;


@Data
public class LoginDTO {
	
	private String userid;
	private String userpw;
	private Boolean rememberMe;

} // end class

 

[ 2 - 2. DAO 인터페이스 생성 ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.persistence;

import org.zerock.myapp.domain.LoginDTO;
import org.zerock.myapp.domain.UserVO;
import org.zerock.myapp.exception.DAOException;

public interface UserDAO {
	
	// 1. 로그인 창에서 입력한 아이디와 암호에 매칭되는 사용자의 정보 획득
	public abstract UserVO selectUser(LoginDTO dto) throws DAOException;

} // end interface

 

[ 2 - 3. DAO 구현 클래스 생성 ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.persistence;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.zerock.myapp.domain.LoginDTO;
import org.zerock.myapp.domain.UserVO;
import org.zerock.myapp.exception.DAOException;

import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;


@Log4j2
@NoArgsConstructor

@Repository
public class UserDAOImpl implements UserDAO {

	@Autowired
	private SqlSessionFactory sqlSessionFactory;
	
	@Override
	public UserVO selectUser(LoginDTO dto) throws DAOException {
		
		log.trace("selectUser({}) invoked.", dto);
		
		SqlSession sqlSession = this.sqlSessionFactory.openSession();
		
		try ( sqlSession ){
			
			String namespace = "org.zerock.myapp.persistence.UserDAO";
			String sqlId = "selectUser";
			String sql = namespace + "." + sqlId;
			
			return sqlSession.<UserVO>selectOne(sql, dto);
			
		} catch(Exception e) {
			throw new DAOException(e);
		} // try - with - resources
		
	} // selectUser

} // end class

 

[ 2 - 4. mapper 생성 ]

 

더보기

[ + 코드 보기 ]

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

<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.zerock.myapp.persistence.UserDAO">

    <select 
        id="selectUser" 
        resultType="org.zerock.myapp.domain.UserVO">

        <![CDATA[ 
            SELECT * 
            FROM tbl_user 
            WHERE userid = #{userid} AND userpw = #{userpw} 
        ]]>

    </select>

    <!-- ========================================================================================= -->

</mapper>

 

[ 2 - 5. 마이바티스에 mapper 등록 ]

 

더보기

[ + 코드 보기 ]

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

<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    
    <!-- 서비스 환경 -->


    <!-- 관리할 Mapper 파일 작성해 주기 (***) -->
    <mappers>

      <mapper resource="mappers/UserMapper.xml" />

      <!-- 인터페이스 방식의 Mapper이 만약 페키지 안에 있다면, 이러한 방법으로 패키지를 지정해 줄 수도 있다. -->
      <package name="org.zerock.myapp.mapper" />

    </mappers>

</configuration>

 

[ 2 - 5. Service 인터페이스 생성 ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.service;

import org.zerock.myapp.domain.LoginDTO;
import org.zerock.myapp.domain.UserVO;
import org.zerock.myapp.exception.DAOException;
import org.zerock.myapp.exception.ServiceException;

public interface UserService {

	// =====================================================================
	// 1. 로그인 창에서 입력한 아이디와 암호에 매칭되는 회원이 있는지 확인
	// =====================================================================
	// ReturnType을 Boolean이 아닌 UserVO로 하는 이유는,
	// 이 객체를 바로 로그인 성공 정보로 Session Scope에 바인딩시키기 위해서이다.
	public abstract UserVO login(LoginDTO dto) throws ServiceException;
} // end interface

 

[ 2 - 6. Service 구현 클래스 생성 ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zerock.myapp.domain.LoginDTO;
import org.zerock.myapp.domain.UserVO;
import org.zerock.myapp.exception.DAOException;
import org.zerock.myapp.exception.ServiceException;
import org.zerock.myapp.persistence.UserDAO;

import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;


@Log4j2
@AllArgsConstructor

@Service
public class UserServiceImpl implements UserService {
	
	// ===============================================================
	
	@Autowired
	private UserDAO userDAO;

	// ===============================================================
	
	@Override
	public UserVO login(LoginDTO dto) throws ServiceException {
		
		log.trace("login({}) invoked.", dto);
		
		try {
			return this.userDAO.selectUser(dto);
		} catch ( DAOException e ) {
			throw new ServiceException(e);
		} // try - catch
		
	} // login
	
	// ===============================================================

} // end class

 

[ 2 - 7. Controller 생성 ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.zerock.myapp.common.SharedScopeKeys;
import org.zerock.myapp.domain.LoginDTO;
import org.zerock.myapp.domain.UserVO;
import org.zerock.myapp.exception.ControllerException;
import org.zerock.myapp.service.UserService;

import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;


@Log4j2
@NoArgsConstructor

@RequestMapping("/user/")
@Controller
public class LoginController {
	
	@Autowired
	private UserService service;
	
	// ===============================================================================================================
	
	@PostMapping("/loginPost")
	// + @ModelAttribute 어노테이션을 통해 모델에 저장할 수 있다.
	public String loginPost ( /* @ModelAttribute("loginDTO") */ LoginDTO dto, Model model, RedirectAttributes rttrs ) 
			throws ControllerException {
		
		log.trace("loginPost({}, {}) invoked.", dto, model);
		// + loginPost(LoginDTO(userid=hohohoh, userpw=1234, rememberMe=true)) invoked.
		// + view에서 post로 정보가 들어온다.
		
		try {
			
			UserVO vo = this.service.login(dto);
			log.info("\t + vo : {}", vo);
			
			if( vo != null ) { 							// 성공했을 때
				
				model.addAttribute(SharedScopeKeys.LOGIN_KEY, vo);
				
				return "user/loginPost";
				// + redirect로 할 경우에는 Request Scope이 깨지기 때문에, model안의 vo가 나오지 못한다.
				
			} else { 									// 실패했을 때
				
				rttrs.addAttribute(SharedScopeKeys.RESULT, "Login Failed.");
				return "redirect:/user/login";
				
			} // if - else
			
		} catch (Exception e) {
			throw new ControllerException(e);
		} // try - catch
		
	} // loginPost
	
	// ===============================================================================================================
	
	@GetMapping("/logout")
	public String logout () {
		
		log.trace("logout() invoked.");
		return "redirect:/user/login";
		
	} // logout
	
	// ===============================================================================================================

} // end class

 

[ + 공유영역 Key 생성 ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.common;

public final class SharedScopeKeys {
	
	public static final String LOGIN_KEY = "__LOGIN_KEY__";
	public static final String RESULT = "__RESULT__";

} // end class

 

[ 2 - 8. View 생성 ]

 

[ + 로그인 페이지 ]

더보기

[ + 코드 보기 ]

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

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>View - user/login.jsp</title>
</head>

<body>

    <h1>/WEB-INF/views/user/login.jsp</h1>
    <hr>

    <form action="/user/loginPost" method="post" style="width: 300px;">
    
        <fieldset style="border: 5px outset gold;">
        
            <legend>Login Form</legend>

            <div><input type="text" name="userid" placeholder="User ID"></div>
            <div><input type="password" name="userpw" placeholder="User PassWord"></div>
            <div>Remember-me <input type="checkbox" name="rememberMe"></div>

            <p></p>

            <div><button type="submit">Sign-in</button></div>
        
        </fieldset>
    
    </form>
    
</body>

</html>

 

[ + 로그아웃 처리 ]

 

더보기

[ + 코드 보기 ]

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

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>View - user/loginPost.jsp</title>
</head>

<body>

    <h1>/WEB-INF/views/user/loginPost.jsp</h1>
    <hr>

    <script>

        setTimeout( function () {
            self.location.href = "/board/list";
        }, 100 );
        
    </script>
    
</body>

</html>

 

[ 2 - 9.  servlet-context.xml에 단순 뷰 호출 등록 ]

 

더보기

[ + 코드 보기 ]

	<!-- 단순 뷰 호출 -->

	<view-controller path="/user/login" view-name="user/login" status-code="200" />
	
	<view-controller path="/board/list" view-name="board/list" status-code="200" />
	<view-controller path="/board/register" view-name="board/register" status-code="200" />
	<view-controller path="/board/get" view-name="board/get" status-code="200" />
	<view-controller path="/board/modify" view-name="board/modify" status-code="200" />
	<view-controller path="/board/remove" view-name="board/remove" status-code="200" />

 

[ 2 - 10. 인터셉터 생성 ]

 

더보기

[ + 코드 보기 ]

package org.zerock.myapp.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;


@Log4j2
@NoArgsConstructor

@Component
public class LoginInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
		
		log.info("========================================================");
		log.trace("1. preHandle(req, res, handler) invoked.");
		log.info("========================================================");
		
		return true;
	} // preHandle

	@Override
	public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler,
			ModelAndView modelAndView) throws Exception {
		
		log.info("========================================================");
		log.trace("2. postHandle(req, res, handler, {}) invoked.", modelAndView);
		log.info("========================================================");

	} // postHandle

	@Override
	public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object handler, Exception e)
			throws Exception {
		
		log.info("========================================================");
		log.trace("3. afterCompletion(req, res, handler, {}) invoked.", e);
		log.info("========================================================");
		
	} // afterCompletion

} // end class

 

[ 2 - 11. servlet-context.xml에 인터셉터 등록 ]

 

더보기

[ + 코드 보기 ]

	<!-- 인터셉터 등록 방법 (****) -->
	<interceptors>

		<interceptor>
			<!-- + path지정한 URI를 보고 가로채서, bean에서 지정한 인터셉터가 처리한다. (***) -->
			<!-- + path는 여러개 지정이 가능하다. ( 이렇게 되면 sampleInterceptor가 2개의 URI를 인터셉트하게 된다. -->
			<!-- + path="/sample/do*"와 같이 와일드 카드를 사용하여 지정해 줄 수도 있다. -->
			<!-- + *는 뒤에 몇글자가 와도 포함되는 와일드 카드고, ?는 단문자만 포함하는 와일드 카드이다. -->
			<!-- + 같은 path를 인터셉트할 경우에는 필터처럼 체이닝되게 된다.(*) -->
			<mapping path="/sample/doA" />
			<mapping path="/sample/doB" />
			<mapping path="/sample/do*" />
			<beans:ref bean="sampleInterceptor" />
		</interceptor>

		<!-- + 이렇게 등록할 경우 /sample/doB로 접속할때 인터셉터 체인이 형성되어 인터셉터가 2번실행되게 된다. -->
		<interceptor>
			<mapping path="/sample/doB" />
			<beans:ref bean="sampleInterceptor2" />
		</interceptor>
		
		<interceptor>
			<mapping path="/user/loginPost" />
			<beans:ref bean="loginInterceptor" />
		</interceptor>

	</interceptors>

 

 

728x90
댓글
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
최근에 올라온 글
Total
Today
Yesterday
공지사항