Filter (Servlet 에서 제공함 (Spring에서도 사용 가능))
걸러내는 거 + 추가하는 거
Spring 은 Servlet 기반 Web application Framework
내부적으로 Dispatcher Servlet 돌아가고 있음
Client 와 Dispatcher Servlet 사이
클라이언트 요청 / 응답 할 때 Filter 가 catch 할 수 있음
Interceptor (Servlet 제공 X (Spring 에서만 제공))
가로채는 거 + 넣어주는 거
전처리, 후처리
Dispatcher Servlet 이 Controller 로 요청을 보내기 전 혹은 Controller 가 응답을 가지고 Dispatcher Servlet 에게 응답을 보내기 전 + View (View Resolver) 가 완성된 다음에
Request 걸러주거나 추가
Response 걸러주거나 수정해서 되돌려줄 수 있음
로깅, 보안, 인증, 인코딩 변환 할 때 사용
요청주소를 catch 할 수 있음 session에 loginMember 가 없으면 못 넘어가게
응답값을 가지고 client 에 돌려줄 때 ex) 응답값이 한국어
영어로 바꿔서 돌려주기
[필터 클래스 생성 방법]
1. jakarta.servlet.Filter 인터페이스 상속 받아야함
2. doFilter() 메서드 오버라이딩
package com.home.board.common.filter;
import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
/* Filter : 요청, 응답 시 걸러내거나 추가할 수 있는 객체
*
* [필터 클래스 생성 방법]
* 1. jakarta.servlet.Filter 인터페이스 상속 받아야함
* 2. doFilter() 메서드 오버라이딩
* */
// 로그인이 되어있지 않은 경우 특정 페이지로 돌아가게 함
public class LoginFilter implements Filter{
// 필터 동작을 정의하는 메서드
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
// ServletRequest : HttpServletRequest의 부모 타입
// ServletResponse : HttpServletResponse의 부모 타입
// HTTP 통신이 가능한 형태로 다운 캐스팅해서 사용해야함
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
// 로그인이 되어있는 상태인지 아닌지 알아야함
// Session 얻어오기
HttpSession session = req.getSession();
// 세션에서 로그인한 회원 정보를 얻어옴
// 얻어왔으나, 없을 때 -> 로그인이 되어있지 않은 상태
if(session.getAttribute("loginMember") == null) {
// /loginError 요청 받아줄 Controller 에 재요청
// resp를 이용해서 원하는 곳으로 리다이렉트
resp.sendRedirect("/loginError");
} else {
// 로그인이 되어있는 경우
// FilterChain
// - 다음 필터 또는 Dispatcher Servlet 과 연결된 객체
// 다음 필터로 요청/응답 객체 전달
// (만약 다음 필터가 없으면 Dispatcher Servlet 으로 전달)
chain.doFilter(request, response);
}
}
}
package com.home.board.common.config;
import java.util.Arrays;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.home.board.common.filter.LoginFilter;
/* 만들어놓은 LoginFilter 클래스가 언제 적용될지 설정 */
@Configuration // 서버가 켜질 때 해당 클래스 내 모든 메서드가 실행됨
public class FilterConfig {
@Bean // 반환된 객체를 Bean 으로 등록 : LoginFilter로 타입을 제한함
public FilterRegistrationBean<LoginFilter> loginFilter() {
// FilterRegistrationBean : 필터를 Bean 으로 등록하는 객체
FilterRegistrationBean<LoginFilter> filter
= new FilterRegistrationBean<>();
// 사용할 필터 객체 추가
filter.setFilter(new LoginFilter());
// /myPage/* : myPage로 시작하는 모든 요청 필터링 해줄거
String[] filteringURL = {"/myPage/*"};
// 필터가 동작할 URL을 세팅
// Arrays.asList(filteringURL)
// -> filteringURL 배열을 List 로 변환
filter.setUrlPatterns(Arrays.asList(filteringURL));
// 필터 이름 지정
filter.setName("loginFilter");
// 필터 순서 지정
filter.setOrder(1);
return filter; // 반환된 객체가 필터를 생성해서 Bean 으로 등록
}
}
MainController
// LoginFilter -> loginError 리다이렉트
// -> message 만들어서 메인페이지로 리다이렉트
@GetMapping("loginError")
public String loginError(RedirectAttributes ra) {
ra.addFlashAttribute("message", "로그인 후 이용해주세요.");
return "redirect:/";
}
URL에 localhost/myPage 접근하면 alert 창 뜸