본문 바로가기

프로그래밍/Spring

인터셉터(Interceptor)를 활용한 로그인 + 세션등록



인터셉터(Interceptor)란?


Controller로 가는 호출을 가로채서 특정 처리를 하는 역할.

   - 아래의 빨간색 부분에서 동작 

사진 출처 : http://blog.daum.net/gunsu0j/165




인터셉터를 지원하는 Spring 메소드


①HandlerInterceptor 인터페이스

②HandlerInterceptorAdapter 추상클래스

- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 

   Object handler)

     Controller 요청 전 실행


- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 

Object handler, ModelAndVeiw modelAndVeiw)

     Controller 처리가 끝나고 화면에 띄어주는 처리 직전에 수행


- afterCompletion() : 모든 처리가 끝난 후 호출





로그인 처리을 위해 DB Table : Users 생성

create table Users (
    Id varchar(50) not null primary key,
    Pw varchar(50) not null,
    userName varchar(100) not null
);
 
insert into Users(Id,Pw,userName) values('user0','0000','이름1');
insert into Users(Id,Pw,userName) values('user1','1111','이름2');
insert into Users(Id,Pw,userName) values('user2','2222','이름3');
insert into Users(Id,Pw,userName) values('user3','3333','이름4');


로그인에 사용할 UsersVO 클래스 작성

public class UsersVO {

	private String id;	
	private String pw;	
	private String userName;

	public String getId() {
		return id;
	}
	public String getPw() {
		return pw;
	}
	public void setPw(String pw) {
		this.pw = pw;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}	
	@Override
		public String toString() {			
			return "UsersVO [Id = " + id+ ",Pw = " + pw + ",UserName = " + userName + "]" ;
		}	
}


로그인 처리 할 SQL문 작성 MyBatis - UsersMapper.xml




	
	
	


UsersDAO 인터페이스와 이를 구현하는 UsersDAOImpl 클래스 정의

public interface UsersDAO {

	// 세션에 등록
	public UsersVO get(UsersVO  usersVO ) throws Exception;

}
@Repository
public class UsersDAOImpl implements UsersDAO{
	
	@Inject
	// Inject어노테이션이 없으면 sqlSession은 null상태이지만
    // Inject어노테이션이 있으면 외부에서 객체를 주입시켜주게 된다. 
    // try catch문, finally문, 객체를 close할 필요가 없어졌다.
	private SqlSession sqlSession;
	
	private static String namespace = "com.test.mapper.usersMapper";
	
	// 세션에 등록
	public UsersVO get(UsersVO  usersVO ){
		return sqlSession.selectOne(namespace+".loginCheck", usersVO );
	}
}

UsersDAOImpl은 UsersDAO인터페이스를 구현하였고, 

DAO(Data Access Object)로 DB에 직접 접근하는 처리를 담당하는 클래스이다. 

해당 클래스에서는 mybatis 접근 객체 : 즉, SqlSessionTemplate 객체를 이용한다.


sqlSession.selectOne("MyBatis Mapper의 namespace명.지정한id",넘겨줄 데이터 객체); 를 이용하여 

MyBatis를 통해 작성한 쿼리를 실행해 UsersVO 객체를 얻어오는 작업을 해준다. 

이때, @Inject나 @Autowired를 통해서 자동 주입을 한다. 

(@Inject와 @Autowired는 ByType(타입이 같은 것을 자동 대입)하는 성질)


서비스 객체에서 DAO를 자동주입할 것임으로 UserDAOImpl 클래스 위에 @Repository 어노테이션을 붙였다.

이것은, 해당 클래스는 DAO 클래스를 의미하고, 자동으로 new 객체를 생성해 준다.


이후, Service 객체에서도 @Inject를 이용해 자동 주입하기 위해 생성해 놓는다.



UsersService 인터페이스와 이를 구현하는 UsersServiceImpl 클래스 정의

public interface UsersService {
	
	public UsersVO getUser(UsersVO  usersVO) throws Exception;
	
}
@Service
public class UsersServiceImpl implements UsersService {
	
	@Inject
	private UsersDAO usersDAO;	
	
	public UsersVO getUser(UsersVO  usersVO) throws Exception {
		return usersDAO.get(usersVO);
	}
}


UsersController 정의

@Controller
public class UserController {
 
    @Inject // 자동 주입
    UserService service;
 
    // 로그인 폼을 띄우는 부분
    @RequestMapping(value="/login.do",method=RequestMethod.GET)
    public String loginForm(){
        return "login/loginForm";
    }
     
    // 로그인 처리하는 부분
    @RequestMapping(value="/loginCheck.do",method=RequestMethod.POST)
    public String loginCheck(HttpSession session,UsersVO usersVO){
        String returnURL = "";
        if ( session.getAttribute("login") != null ){
            // 기존에 login이란 세션 값이 존재한다면
            session.removeAttribute("login"); // 기존값을 제거해 준다.
        }
         
        // 로그인이 성공하면 UsersVO 객체를 반환함.
        UsersVO vo = service.getUser(UsersVO);
         
        if ( vo != null ){ // 로그인 성공
            session.setAttribute("login", vo); // 세션에 login인이란 이름으로 UsersVO 객체를 저장해 놈.
            returnURL = "redirect:/main"; // 로그인 성공시 메인페이지로 이동하고
        }else { // 로그인에 실패한 경우
            returnURL = "redirect:/login"; // 로그인 폼으로 다시 가도록 함
        }
         
        return returnURL; // 위에서 설정한 returnURL 을 반환해서 이동시킴
    }
 
    // 로그아웃 하는 부분
    @RequestMapping(value="/logout.do")
    public String logout(HttpSession session) {
        session.invalidate(); // 세션 초기화
        return "redirect:/login.do"; // 로그아웃 후 로그인화면으로 이동
    }
} // end of controller


============================================================================

인터셉터 부분 (AuthLoginInterceptor)

// 로그인처리를 담당하는 인터셉터
public class AuthLoginInterceptor extends HandlerInterceptorAdapter{
 
    // preHandle() : 컨트롤러보다 먼저 수행되는 메서드
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // session 객체를 가져옴
        HttpSession session = request.getSession();
        // login처리를 담당하는 사용자 정보를 담고 있는 객체를 가져옴
        Object obj = session.getAttribute("login");
         
        if ( obj == null ){
            // 로그인이 안되어 있는 상태임으로 로그인 폼으로 다시 돌려보냄(redirect)
            response.sendRedirect("/login.do");
            return false; // 더이상 컨트롤러 요청으로 가지 않도록 false로 반환함
        }
         
        // preHandle의 return은 컨트롤러 요청 uri로 가도 되냐 안되냐를 허가하는 의미임
        // 따라서 true로하면 컨트롤러 uri로 가게 됨.
        return true;
    }
 
    // 컨트롤러가 수행되고 화면이 보여지기 직전에 수행되는 메서드
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        // TODO Auto-generated method stub
        super.postHandle(request, response, handler, modelAndView);
    }     
}


마지막으로 servlet-context.xml에 추가설정


1
2
3
4
5
6
7
8
9
10
11
<!-- 인터셉터 객체 생성 -->
<beans:bean id="AuthLoginInterceptor" class="com.test.login.AuthLoginInterceptor">
</beans:bean>
<!-- Interceptor 설정 -->
<interceptors>
    <interceptor>
        <mvc:mapping path="/**"/>         
        <mvc:exclude-mapping path="/resources/**"/>
        <beans:ref bean="AuthLoginInterceptor"/>
    </interceptor>
</interceptors>
cs