seong
(13)블로그 만들기 웹에서 Interceptor 구현 (WebMvcConfigurer 사용) 본문
Interceptor
컨트롤러로 들어오는 HttpRequest, HttpResponse를 가로채는 역할을 한다.
예를 들어 컨트롤러에 글을 삭제 하는 로직이 있다.
글은 "해당글의 작성자"만이 삭제를 할 수 있다, 여기서 Interceptor 를 이용해 삭제를 하기 전 작성자가 아니라면 컨트롤러가 동작 하지 않게 한다.
필터와 인터셉터는 비슷한 역할을 하지만 다르다!
Interceptor 호출 시점은 3가지가 있다.
1. preHandle : 컨트롤러가 호출 되기 전
2. postHandle: 컨트롤러가 실행 된 후
3. afterComplete : 컨트롤러 -> View 모든 동작이 끝난 후
구현해보기
필요한 환경 설정 셋팅
보통 Interceptor 구현 하기 위해서 2가지가 필요하다.
1. Interceptor 핸들러
2. 웹에서 Interceptor 경로를 설정해줄 WebMvcConfigurer이 필요하다.
주소에 특정 패턴 부여
핸들러 작성 전 인증이 필요한 컨트롤러 주소에 특정 패턴을 준다.
패턴을 주는 이유는 인터셉터를 할 부분을 더 효율적으로 다루기 위해서 이다 .
View의 경로만 리턴 해줄 경우 아래 처럼 /s를 추가
view 경로 확인
추가적으로 데이터를 리턴 해줄 때는 /api도 붙여 주었다.
/s : 인증이 필요한 컨트롤러
/api : 데이터를 리턴해주는 컨트롤러
위의 코드에선 return에 데이터를 리턴하고, 인증이 필요하기 때문에 주소 앞에 /s/api를 넣어주었다.
/s/api는 작성자 본인이 필요에 따라 아무렇게 정해도 된다.
@ResponseBody가 적혀있다면 모두 /api가 적힌다.
Interceptor 핸들러 작성
현재 Ajax를 통해 통신을 하고 있다.
Ajax는 CMRespDto라는 데이터를 전달하고있다.
단지 주소(View의 주소)를 전달 하면 응답에 Redirect 해서 주면 되지만 JSON 데이터 타입은 인터셉터가 전달을 할 수 없기 때문에
직접 로직을 작성해 줄 필요가 있다.
package site.metacoding.red.handler;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import site.metacoding.red.domain.users.Users;
import site.metacoding.red.web.dto.response.CMRespDto;
public class LoginIntercepter implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// System.out.println("================");
// System.out.println(request.getRequestURI());
// System.out.println("================");
String uri = request.getRequestURI();
HttpSession session = request.getSession();
Users principal = (Users) session.getAttribute("principal");
if(principal == null) {
if(uri.contains("api")) {
// System.out.println("===========");
// System.out.println("API 가 주소에 있음");
//response.setHeader("Content-Type", "application/json; charset=utf-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = response.getWriter();
CMRespDto<?> cmRespDto = new CMRespDto<>(-1, "인증이 필요합니다", null);
ObjectMapper om = new ObjectMapper();
String json = om.writeValueAsString(cmRespDto);
out.println(json);
}else {
System.out.println("===========");
System.out.println("API 가 주소에 없음");
response.sendRedirect("/loginForm");
}
return false;
}
return true;
}
}
위 코드 동작
데이터의 타입은 JSON으로 했기 때문에 꼭 JSON으로 변환해서 전달 해 주어야 한다!
WebMvcConfigurer 작성 ( 경로를 담당 )
package site.metacoding.red.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import site.metacoding.red.handler.LoginIntercepter;
/*.excludePathPatterns("/s/boards/**") => /s/boards로 시작하는 모든것을 제외*/
import site.metacoding.red.handler.TestIntercepter;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginIntercepter())
.addPathPatterns("/s/**");
}
}
registry.addInterceptor는 만들 Interceptor객체를 연결 한다는 뜻이다.
.addPathPatterns("/s/boards/**"); => /s/boards로 시작하는 모든 경로를 포함.
.excludePathPatterns("/s/boards/**"); => /s/boards로 시작하는 모든 경로를 제외함.
/s* => s뒤의 주소 한개 까지만 읽기 가능 /s/boards는 가능 /s/boards/1 은 불가능
Ajax,Form태그,Controller 등 경로가 있는 곳은 모두 체크해 바꿔준다!
아래 처럼 찾아서 모두 수정
결과 확인 해보기
1. 좋아요는 데이터를 응답 받는 코드이다.
그러므로 Intercetptor에서 응답 데이터를 만들어서 전달 해주고 확인
2. 글쓰기 폼 확인
로그인 하지 않고 writeForm으로 이동
세션값이 null이고, 주소값에 api가 있지 않기 때문에 /loginForm을 썻다. 제대로 전달이 되었다
'Spring > 블로그 만들기' 카테고리의 다른 글
블로그 만들기 기능 - 백엔드에서 유효성 검사 Validation 라이브러리 사용 (0) | 2022.09.21 |
---|---|
블로그 만들기 기능 - 프론트에서 유효성 검사 Validation체크(한글,공백,이메일형식) (0) | 2022.09.21 |
(11)블로그만들기 Session 저장 공간 활용 - 검색 후 keyword,currentPage값 가져가기. (0) | 2022.09.19 |
(10)블로그만들기 Ajax - boards 삭제,수정 만들기 (0) | 2022.09.17 |
(9)블로그만들기 - 쿠키에 저장 된 값 Request Header에 담아 가져가기(로그인) (0) | 2022.09.16 |