2013년 9월 5일 목요일

Session 관리

오랫동안 자리를 비우거나 할때 session 이 유실되면 로그인 정보와 동기화가 맞지 않아 오류를 낼 때가 있다. 모든 페이지에서 세션검사를 하는 것은 매우 비효율적이다. Interceptor 를 통해서 손쉽게 관리가 가능하다.
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
     Object handler) throws Exception {
  
  HttpSession session = request.getSession(false);
  
  if(session == null || session.getAttribute("SPRING_SECURITY_CONTEXT") == null){
   
   logger.info("------------NOT LOGINED--------------");
   // 첫 로그인
  } else if(session != null && session.getAttribute("sessionVo") != null
          && session.getAttribute("SPRING_SECURITY_CONTEXT") != null){
   
   logger.info("--------------LOGINED----------------");
   
  } else if(session != null && session.getAttribute("SPRING_SECURITY_CONTEXT") != null
          && session.getAttribute("sessionVo") == null){   
      
   logger.info("----------SESSIONVO EXPIRED----------");
   
   session.invalidate();
        
   response.sendRedirect(request.getRequestURI());
      
   return false;   
  }
    
  return true;
 }

코드 수정함 원래 목적은 session 이 없을때는 spring-security 로 넘기는 식으로 하려 했으나 interceptor의 개입시점이 spring-security 보다 늦는 문제가 있다 그래서 sessionVo 가 소멸됬을때 session 전체를 소멸하고 다시 request url 로 이동하는 식으로 했다 이는 POST 방식일때 같은 url 로 get방식으로 이동하므로 restful 스타일에 알맞다

Interceptor

Controller 가 엄청 많은데 log 형식을 바꾼다면 모든 클래스에 손을 대야한다. 그러나 Interceptor 를 활용하면 손쉽게 관리할 수 있다.
package com.jetddo.study.interceptor;

import java.util.Enumeration;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;


@Component
public class LoggingInterceptor implements HandlerInterceptor {

   private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);

   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
     Object handler) throws Exception {
    
    logger.info("-------------------------------");
       logger.info("url: "+request.getRequestURI());
       
       String param = "";
       
       Enumeration< ? > e = (Enumeration< ? >)request.getParameterNames();
       while(e.hasMoreElements()){
        
        String name = (String)e.nextElement();
        
        param += "["+name+": "+request.getParameter(name)+"]";
       }
       
       if(param.trim().length() > 0){
        logger.info("params: "+param);
       }
       
       return true;
   }
   
   public void postHandle(HttpServletRequest request, HttpServletResponse response, 
     Object handler, ModelAndView modelAndView) throws Exception {

   }

   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
     Object handler, Exception ex) throws Exception {

   }
}

위와 같이 작성 후
 
  
   
   
  
  
   
   
  
 
servlet-context.xml 에 위와 같이 작성한다.

@Autowired, @Resource

1. @Autowired Type 을 통해 자동주입 ( 인터페이스를 통해 2개의 구현체가 있을 경우 사용 불가능) 2. @Resource name 을 통해 자동 주입 ex)
@Resource(name="userDaoImpl") 
UserDao userDao;

//UserDaoImpl 이라는 Class 를 주입함
//spring 설정 파일에서 context-scan 를 사용하거나 bean 객체로 등록되어야 함