2022-04-05(화)
인터셉터
인터셉터
필터 기능을 수행 ← 기능의 삽입, 삭제가 쉽다
페이지 컨트롤러의 request handler 실행 전후에 인터셉터가 개입
요청 -> Spring Boot -> 인터셉터 ->
사용자 인증, 권한 검사, 파라미터값 검증, 압축해제, 암호해제, 로그 출력
클라이언트가 데이터를 보냈으면 압축 해제 작업이라든가
리턴값 압축, 리턴값을 Client가 요구하는 방식으로 인코딩, 리턴값을 암호화 등
인터셉터 활용
<<인터셉터>> 로그인 여부 검사
add(), update(), delete() -> BoardHandler
<<Front Controller>> DispatcherServlet
-> 인터셉터
규칙에 따라 call 한다
afterCompletion 뷰 리졸버 개념을 배우기 전까지는
전처리
후처리
preHandle()
postHandle()
MessageConverter ← 리턴된 자바 객체를 JSON 문자열로 바꿔준다
(jackson의 ObjectMapper를 쓴다)
Deprecated
Interceptor 만들기
<<Interface>> HandlerInterceptor
preHandle()
postHandle()
afterCompletion()
인터페이스 3개 메서드 중에서 관심 있는 건 preHandle() 1개인데 나머지 메서드들도 빈 메서드라도 구현해야 됨
<<abstract>> HandlerInterceptorAdapter
인터페이스 메서드를 미리 구현함
단, 구현 코드는 없음
상속받는 쪽에서 관심 있는 메서드만 오버라이딩 하면 됨!
<<concrete>> MyInterceptor
관심 있는 메서드만 오버라이딩 하면 된다.
Interceptor 만들기 - default 문법 등장
default 메서드로 선언하면 미리 메서드를 구현할 수 있다.
→ Adaptor 클래스의 효용성이 사라짐
→ deprecated로 처리됨
스프링 버전에 따라 달라짐
2015년 전에 구축한 프로젝트는 HandlerInterceptorAdapter를 사용
신규 프로젝트는 HandlerInterceptor 사용
package com.eomcs.mylist.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
// 사용자 인증 여부를 검사하는 인터셉터
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("preHandle() 호출됨!");
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle() 호출됨!");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
}
2단계 - 스프링부트에 인터셉터를 등록한다.
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-config-enable
package com.eomcs.mylist.conf;
import org.springframework.context.annotation.Configuration;
@Configuration
// 다음 클래스는 설정에 관련된 일을 하는 클래스임을 선언한다.
// 스프링 부트는 이 애노테이션이 붙은 클래스에 대해 관련 메서드를 호출하여 내부 설정에 반영한다.
public class MvcConfiguration {
}
스프링 부트는 이 애노테이션이 붙은 클래스에 대해
관련 메서드를 호출하여 내부 설정에 반영한다.
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-config-interceptors
인터셉터를 언제 넣을 거냐
@Configuration
// 다음 클래스는 설정에 관련된 일을 하는 클래스임을 선언한다.
// 스프링 부트는 이 애노테이션이 붙은 클래스에 대해 관련 메서드를 호출하여 내부 설정에 반영한다.
public class MvcConfiguration implements WebMvcConfigurer {
// WebMvcConfigurer 인터페이스
// => 이 규칙에 따라 메서드를 작성하면 그 메서드가 의도한 대로
// 스프링 부트는 해당 메서드를 호출하여 그 메서드가 요구하는 대로 설정한다.
// 인터셉터를 추가하고 싶다면 다음 메서드를 규칙에 따라 정의하라!
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("MvcConfiguration.addInterceptors() 호출됨!");
// 이 메서드가 정의되어 있다면 스프링 부트는 이 메서드를 호출하여
// 추가할 인터셉터의 정보를 InterceptorRegistry로 받는다.
registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**");
}
}
@Configuration 애노테이션 붙어서 호출되는 거
규칙에 따라 만들면 규칙에 따라서 설정을 수행한다
@Component ← 스프링이 관리해야 될 대상
애노테이션으로 하는 게 아니라 명시적으로 생성
@RequestMapping("/board/list")
public Object list() {
return new ResultMap().setStatus(SUCCESS).setData(boardService.list());
}
응답 데이터는 규칙이 명확해야 한다
fetch("/board/list")
.then(function(response) {
return response.json();
})
.then(function(result) {
if (result.status == "fail") {
window.alert("서버 요청 오류!");
console.log(result.data);
return;
}
for (var board of result.data) {
var tr = document.createElement("tr");
tr.innerHTML = `<td>${board.no}</td>
<td><a href="?content=/board/view.html&no=${board.no}">${board.title}</a></td>
<td>${board.writer.name}</td>
<td>${board.viewCount}</td>
<td>${board.createdDate}</td>`;
tbody.appendChild(tr);
}
});
result.data ← 성공했으면 list가 들어 있고 실패했으면 실패 이유가 들어있다
// 3) 서버에서 데이터 가져오기
fetch(`/board/get?no=${no}`)
.then(function(response) {
return response.json();
})
.then(function(result) {
// 4) 연락처 상세 정보를 화면에 출력한다.
if (result.status == "fail") {
window.alert("서버 요청 오류!");
console.log(result.data);
return;
}
var board =result.data;
xNo.value = board.no;
xTitle.value = board.title;
xContent.value = board.content;
xWriter.innerHTML = board.writer.name;
xViewCount.innerHTML = board.viewCount;
xCreatedDate.innerHTML = board.createdDate;
});
http://localhost:8080/board/get?no=14
http://localhost:8080/board/get?no=200
자바스크립트 객체로 바꿀 때까지 기다리면 안 되니까 비동기로 처리됨
리턴값을 기다리게 되면 다른 작업을 못하는 락이 걸림
then 이라는 메서드
로그인 한 상태에서는 나오는데
빈 문자열은 못 바꿈
JSON 문자열 -> 자바스크립트 객체
문자열 자체가 빈 문자열이면 자바스크립트 객체로 못 바꿈
JSON 형식의 문자열이 아니야! 에러남
ResultMap 객체를 JSON 문자열로 바꿔줘야 됨
인터셉트는 자동으로 안 바꿔주기 때문에 수동으로 바꿔줘야 됨
jackson
https://velog.io/@banana/2022-01-24월-11주차-1일
영어로 못 바꾸면 물음표로 뜸
response.setContentType("application/json;charset=UTF-8");
자바 18버전은 내부적으로
이제 한글 안 깨짐
window.alert(result.data);
window 생략 가능
// 로그인 여부 검사
HttpSession session = request.getSession();
Member loginUser = (Member) session.getAttribute("loginUser");
if (loginUser == null) {
// 로그인을 하지 않았으면 오류 메시지를 JSON 형식으로 직접 응답한다.
ObjectMapper jsonConverter = new ObjectMapper();
String json = jsonConverter.writeValueAsString(new ResultMap()
.setStatus(ResultMap.FAIL)
.setData("로그인 하지 않았습니다."));
response.setContentType("application/json;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write(json);
// 로그인 여부 검사
HttpSession session = request.getSession();
Member loginUser = (Member) session.getAttribute("loginUser");
if (loginUser == null) {
// 로그인을 하지 않았으면 오류 메시지를 JSON 형식으로 직접 응답한다.
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(new ObjectMapper().writeValueAsString(new ResultMap()
.setStatus(ResultMap.FAIL)
.setData("로그인 하지 않았습니다.")));
return false; // 페이지 컨트롤러를 실행하지 말고 즉시 응답하라!
}
저 부분 지우기
Author And Source
이 문제에 관하여(2022-04-05(화)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@banana/2022-04-05화저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)