본문 바로가기

   
Programming/Java

Java Interceptor resources 및 특정 경로를 소스에서 제외하는 방법(스프링 버전 3.1.1)

반응형

Java Interceptor resources 및 특정 경로를 소스에서 제외하는 방법(스프링 버전 3.1.1)

최근에 Java 언어를 이용해 Spring 환경에서 웹페이지 기능을 만들고 있습니다. 사이트 기능 중 필요했던 기능이 로그인한 사용자만 페이지를 이용할 수 있도록 하기 위해 정보를 찾아보니 Interceptor를 활용하면 페이지 단위별로 작업을 하지 않아도 한 방에 해결할 수 있을 것 같았습니다.

Spring 프레임워크 버전별로 환경 구성이 다르기에 정보를 검색하는 것을 참고할 수 있었으나 저와 비슷한 환경에 대한 글은 대체로 많이 없었고 예외 사항도 꽤 있었던 것 같습니다.

Interceptor를 사용하기 위해서는 설정이 필요했습니다. WEB-INF/spring/servlet-context.xml 파일에 인터셉터를 사용하기 위해 아래 소스를 추가하였습니다.

	<!-- Interceptors-->
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			 <bean class="com.zzarungna.controllers.InterCepter" /> 
		</mvc:interceptor>
	</mvc:interceptors>

 


인터셉터를 사용하기 위한 설정을 추가하였고 로그인된 대상만 페이지에 접근할 수 있도록  로그인하지 않은 경우 아래 소스와 같이 페이지 리다이렉트를 처리하였더니 리다이렉트 횟수가 많다고 하며 에러가 나더군요.

package com.zzarungna.controllers; 

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.servlet.http.HttpSession; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 

public class InterCepter extends HandlerInterceptorAdapter{ 

@Override 
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception { 
  //로그인 세션이 없다면 login 페이지로 이동 
  String id = (String)request.getSession().getAttribute("id");

  if(id==null){ 
      response.sendRedirect("/login"); 
      return false; 
  } 

  return true; 
  } 

} 

 

문제는 로그인하지 않았을 때 로그인 페이지로 보내게 되는데 해당 페이지로 접근하여도 인터셉터에서 설정 자체를 모든 요청에 대해 인터셉터가 걸려 있기에 로그인 페이지로 보낸다고 해도 무한 리다이렉트가 걸릴 뿐 멈출 수 있는 곳이 없었습니다.

그래서 소스 수정을 통해 로그인 페이지 요청이 오는 경우는 인터셉터에서 제외해주는 수정이 필요했습니다. 그렇게 특정 경로는 예외로  처리하기 위해 인터셉터 매뉴얼을 확인해 보니 WEB-INF/spring/servlet-context.xml 파일에 exclude-mapping을 사용하면 된다고 하더군요.

소스 수정을 하고 한창 서버 재시작을 여러 차례 진행하였으나 지속해서 오류가 나고 exclude-mapping을 못 찾는다는 에러만 나더군요.

나중에 확인해 보니 exclude-mapping은 스프링 MVC 버전 3.2부터 지원이 된다고 합니다. 제가 사용하는 스프링 프레임워크 환경의 버전을 확인해보니 3.1.1 버전이더군요.

스프링 프레임워크 버전은 pom.xml 문서에서 확인이 가능하며 저의 경우는 아래 소스 코드와 같이 스프링 프레임워크 버전이 3.1.1 버전이었습니다.

 

<properties>
  <java-version>1.6</java-version>
  <org.springframework-version>3.1.1.RELEASE</org.springframework-version>
</properties>

 

특정 경로를 설정으로 지정하면 코드도 간결하고 더 좋았을 테지만 스프링 버전업을 하기 보다는 Interceptor 클래스를 이용해 특정 URL은 인터셉터 요청 항목에서 제외하는 게 좋을 것 같아 아래 소스 코드와 같이 코드를 수정하였습니다.

package com.zzarungna.controllers; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.servlet.http.HttpSession; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 

public class InterCepter extends HandlerInterceptorAdapter{ 

@Override 
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception { 
  //로그인 세션이 없다면 login 페이지로 이동 
  String id = (String)request.getSession().getAttribute("id"); 
  String requestUrl = request.getRequestURL().toString(); 

  //로그인 경로 제외 
  if(requestUrl.contains("/login")){ 
      return true;
  } 

  //리소스 경로 제외 
  if(requestUrl.contains("/resources")){ 
      return true;
  } 

  if(id==null){ 
      response.sendRedirect("/login");
      return false; 
  } 

  return true; 
} 

} 

 

위와 같이 Interceptor 클래스에서 로그인 경로를 제외한 후 로그인하지 않은 대상이 사이트에 접근한 경우 로그인 페이지로 리다이렉트 처리를 할 수 있었습니다.

 

개인적으로 인터셉터를 활용하기 위한 클래스를 컨트롤러가 패키지가 아닌 다른 패키지에서 생성하니 제대로 작동하지 않는 문제도 있었습니다. 혹시라도 인터셉터가 제대로 동작되지 않는 분들은 인터셉터 클래스를 컨트롤러 패키지에 생성해 보시기 바랍니다.

 

resource 경로를 제외한 이유는 로그인 페이지가 웹에 표시되는데 해당 로그인 페이지에서 참조하고 있는 CSS와 Javascript 파일은 모두 resource 폴더에서 관리되고 있었기에 Interceptor에서 모든 요청을 제어하다 보니 해당 경로를 참조하고 있는 파일을 불러올 수 없어 웹페이지가 제대로 표시되지 않는 현상이 생겨 resources 경로도 인터셉터 요청에서 제외되도록 수정이 필요했습니다.

개인적으로 Java Spring Framework를 활용하며 인터셉터를 활용하면서 테스트 시간과 삽질을 하였기에 저와 비슷한 현상으로 문제를 겪고 있는 분들에게 참고하실만한 내용이 되었기를 바랍니다

반응형