Whiteship's Note

Intercepting requests 예제

Spring/Chapter 13 : 2007.05.17 12:36


어떤 서비스를 로그인 한 유저에게만 제공하고 싶다면...

request를 처리하는 메소드 내에서

if (request.getSession.getAttribute("user") != null)
    throw LoginRequiredException();

이런식으로 예외를 발생시키고 이 예외가 발생할 때마다 로그인 페이지로 이동 시키게 할 수 있습니다.

하지만 저런 코드가 여러 부분에서 필요하게 될 것이고 이것을 AOP를 적용하여 Aspect로 빼내고 싶어지는 것이 당연합니다.

그런데 Spring AOP가 조금 복잡하자나열(2.0 에서는 많이 나아졌지만)...pointcut 정의 해줘야 하는데 문법도 좀 희한하고 advice 종류도 다양한데 특정 인자를 받아와야 하는 방법을 써야 하니까 args 표현식을 써야 하고.. 등등 복잡합니다.

그래서.. 간단하게 HadlerMapping과 HandlerInterceptor 를 사용해서 AOP를 적용할 수 있습니다. 요녀석을 사용하면 HttpRequest와 HttpResponse를 인자로 받는 Around Advice를 적용하는 기분이 들 것입니다.

1. Handler Mapping 등록하기
- Handler Mapping을 여러 개 사용할 수 있습니다. 그리고 그 들간의 순서를 order 속성을 사용하여 지정해 줄 수 있습니다. viewResolver를 여러 개 등록하는 거랑 같습니다.

    <bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
        <property name="order" value="2" />
    </bean>

기존에 사용하던 HandlerMapping은 BeanNameUrlHandlerMapping으로 암묵적으로[각주:1] 사용하고 있었습니다.

이 녀석을 위에 보시다시피 명시적으로 표기해 주고 순서를 두 번째로 지정합니다. 다음으로는 User를 체크해야 할 request를 처리할 HandlerMapping을 등록합니다.

<bean id="userCheckHandlerMapping"
          class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="order" value="1" />
        <property name="interceptors">
            <list>
                <ref bean="memberCheckInterceptor"/>
            </list>
        </property>
        <property name="mappings">
            <value>
                /board/createArticle.html = createArticleController
                /board/createReply.html = createReplyController
                /createAuction.html = createLPAuctionController
                /auction/insertAuctionReply.html = insertAuctionReplyController
                /fileUpload.html = uploadFileController
            </value>
        </property>
    </bean>

SimpleUrlHandlerMapping을 사용하여 다섯개의 request를 처리할 것입니다. 저 request 들은 모두 memberCheckInterceptor를 거쳐가게 되어있습니다.

따라서 이제 memberCheckInterceptor만 구현해 주면 구현이 끝납니다.

2. Interceptor 만들기

public class MemberCheckInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(request.getSession().getAttribute("user") != null)
            return true;
        else {
            response.sendRedirect("http://localhost:8080/classicMania/login.html");
            return false;
        }
    }
}

와.. 간단합니다. user라는 이름의 객체가 세션에 있으면 계속 request를 처리하고 아니면 login 페이지로 넘어가도록 합니다. true는 계속 처리 false는 처리 안하게 합니다. Around Advice에서 해당 메소드를 실행 할지 말지 선택할 수 있었던 것과 유사하지 않나효.

3. 실행


로그인 안 한 상태에서 파일 업로드 페이지로 가려고 하면 => 로그인 페이지로 이동
로그인 한 상태라에서 파일 업로드 페이지로 가려고 하면 => 파일 업로드 페이지 요청을 처리합니다.
  1. 명시적으로 handleMapping을 등록하지 않으면 DispacherSevlet이 알아서 이녀석을 만들어서 사용하기 떄문이빈다. [본문으로]
top




: 1 : ··· : 5 : 6 : 7 : 8 : 9 : 10 : 11 : 12 : 13 : ··· : 28 :