delpho
Spring에 대하여 - 3 본문
1. Servlet Filter와 Spring Interceptor의 차이는 무엇인가요?
# Filter
- 프론트에서 Dispatcher Sevlet에 요청이 전달되기 전/후에 url 패턴에 맞는 모든 요청에 대해 부가작업을 처리할 수 있는 기능
- DS는 스프링의 가장 앞단에 존재하는 프론트 컨트롤러이므로, 필터는 스프링 범위 밖에서 처리가 되는 것임!
- 스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에 의해 관리가 되는 것이고(스프링 빈으로 등록은 된다), 디스패처 서블릿 전/후에 처리하는 것
- 필터를 추가하기 위해서는 javax.servlet의 Filter 인터페이스를 구현(implements)해야 하며 이는 다음의 3가지 메소드를 가지고 있다.
- init 메소드
- doFilter 메소드
- destroy 메소드
# Interceptor
- Spring이 제공하는 기술
- Dispatcher sevlet이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공
- 필터와 달리 Spring Context에서 동작함.
- 동작 과정
- 1. 디스패처 서블릿은 핸들러 매핑을 통해 적절한 컨트롤러를 찾도록 요청하는데, 그 결과로 실행 체인(HandlerExecutionChain)을 돌려줌
- 2. 실행 체인에 1개 이상의 인터셉터가 등록되어 있다면 순차적으로 인터셉터들을 거쳐 컨트롤러가 실행되도록 하고, 인터셉터가 없다면 바로 컨트롤러를 실행!
- 인터셉터를 추가하기 위해서는 org.springframework.web.servlet의 HandlerInterceptor 인터페이스를 구현(implements)해야 하며, 이는 다음의 3가지 메소드를 가지고 있다.
- preHandle 메소드
- postHandle 메소드
- afterCompletion 메소드
2. Spring에서 CORS 에러를 해결하기 위한 방법을 설명해주세요.
# Origin (출처) 란?
- 프로토콜 + Host + Port
# 웹에 존재하는 두가지 정책 - SOP (Same Origin Policy) / CORS (Cross Origin Resource Sharing)
- SOP
- 같은 출처에서만 리소스를 공유할 수 있다.
- 같은 Origin을 사용하면 같은 출처
- 리소스가 자신의 출처와 다를 경우, 브라우저는 교차출처 요청을 실행
- 만약, CORS 정책을 위반하는 요청에 서버가 정상적으로 응답하더라도, 브라우저가 응답을 분석하여 CORS 정책에 위반되면 응답 처리 X
- 출처를 비교하는 로직은 브라우저에 구현된 스펙!
- 리소스가 자신의 출처와 다를 경우, 브라우저는 교차출처 요청을 실행
- CORS
- 추가 HTTP 헤더를 사용하여, 한 출처에서 실행중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제
- CORS 기본 동작 과정
- 1. 클라이언트에서 HTTP 요청의 헤더에 Origin을 담아 전달
- 다른 Origin의 리소스 요청시 클라이언트는 HTTP 요청 보냄
- 요청헤더의 ORigin 필드에 요청을 보내는 Origin 담아보냄
- 2. 서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트에 응답
- 서버가 허락하는 Origin을 클라이언트에 응답
- 3. 클라이언트에서, 자신이 보냈던 요청의 Origin과 서버에서 보내준 Access-Control-Allow-Origin 비교
- 1. 클라이언트에서 HTTP 요청의 헤더에 Origin을 담아 전달
# Spring에서 CORS 에러 해결 방법
1. CrossOrigin 어노테이션 사용
- 컨트롤러에서 특정 메서드 혹은 컨트롤러 상단부에 @CrossOrigin 추가
- 단점 : 컨트롤러 만을수록 설정해야하는 어노테이션 많아짐.
2. WebMvcConfigurer에서 설정
Spring Initializer 를 이용해서 프로젝트를 만들었다면 다음과 같은 main 함수가 존재
@SpringBootApplication
public class RestServiceCorsApplication {
public static void main(String[] args) {
SpringApplication.run(RestServiceCorsApplication.class, args);
}
}
해당 코드에서 Bean으로 Configurer를 추가해주기!
@Configuration 을 허용한 클래스에서 등록을 할 수도 있다!
@SpringBootApplication
public class RestServiceCorsApplication {
public static void main(String[] args) {
SpringApplication.run(RestServiceCorsApplication.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://front-server.com");
}
};
}
}
3. CorsFilter 생성
- 필더 폴더 생성 후 클래스 생성.
- 해당 클래스를 Bean으로 등록 (@Component), filter 인터페이스 구현
- Filter는 꼭 javax.servlet의 필터를 사용해야 함!
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
- 필터가 실제로 수행할 doFilter를 커스텀
- 우리가 필요한 헤더를 OPTIONS 가 잘 확인할 수 있도록 설정해줄 수 있다.
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods","*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization");
if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
}else {
chain.doFilter(req, res);
}
}
@Override
public void destroy() {
}
}
3. Bean/Component 애노테이션에 대해서 설명해주시고, 둘의 차이점에 대해 설명해주세요.
# Bean / Component 어노테이션의 공통점
- Spring(IOC) Container에 Bean을 등록하도록 하는 메타데이터를 기입한다.
# Bean / Component 어노테이션의 차이점
- 둘의 용도가 다름!
- @Component
- 스프링이 런타임시에 컴포넌트스캔을 하여 자동으로 빈을 찾고(detect) 등록하는 애노테이션
- 개발자가 직접 작성한/컨트롤이 가능한 Class를 Bean으로 등록하기 위한 어노테이션
- 클래스 레벨에서 선언
- 싱글톤 클래스 Bean을 생성
- @Bean
- 반환되는 객체(인스턴스)를 개발자가 수동으로 빈으로 등록하는 애노테이션
- 반환 값이 바로 Bean으로 등록
- 외부 라이브러리 또는 이미 정의되어 있는 객체들이 서로 종속성을 가지고 있을 경우의 빈 등록에 사용하는 어노테이션
- 이미 정의된 기본 객체를 재정의하거나 내가 만든 객체의 종속성을 위해 빈을 등록할 때 사용
- 메소드 단위에서 개발자가 외부 라이브러리 및 개발자가 정의하지 않은 객체를 유연하게 넘기기 위해 사용
- @Bean은 메소드 레벨에서 선언
- 반환되는 객체(인스턴스)를 개발자가 수동으로 빈으로 등록하는 애노테이션
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl();
}
}
4. POJO란 무엇인가요? Spring Framework에서 POJO는 무엇이 될 수 있을까요?
# POJO란
- 객체 지향적인 원리에 충실하면서 환경과 기술에 종속되지 않고 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트 (Java에서 제공하는 API 외에 종속 X)
- 특정 인터페이스를 구현하거나 또는 클래스를 상속하지 않는 일반 자바 객체
- 일반적인 자바 객체를 칭하기 위한 별칭 개념!
# Spring에서 POJO는?
음.... Java API에서 제공하는 것만 이용한 모든 class..? (명확한 답은 잘 모르겠다...)
출처
https://mangkyu.tistory.com/173
[Spring] 필터(Filter) vs 인터셉터(Interceptor) 차이 및 용도 - (1)
Spring은 공통적으로 여러 작업을 처리함으로써 중복된 코드를 제거할 수 있도록 많은 기능들을 지원하고 있다. 이번에는 그 중에서 필터(Filter) vs 인터셉터(Interceptor)의 차이에 대해 알아보고자
mangkyu.tistory.com
[WEB] 📚 CORS 개념 💯 완벽 정리 & 해결 방법 👏
CORS(Cross Origin Resource Sharing) CORS 정책은 우리가 가져오는 리소스들이 안전한지 검사하는 관문이다. 웹개발을 하는 사람들은 이 CORS 정책위반으로 인해 에러가 나는 상황을 많이들 겪어봤을것이라
inpa.tistory.com
[Spring Boot] CORS 를 해결하는 3가지 방법 (Filter, @CrossOrigin, WebMvcConfigurer)
Server Side Template 방식이 아닌 Front와 Back 으로 나눠서 인프라를 구성해본 경험이 있는 사람들에게는 Cors가 매우 친숙할 수 있다. 현재 개발 흐름에서 웹 프로젝트를 진행하다가 Cors 를 만날 확률은
wonit.tistory.com
https://youngjinmo.github.io/2021/06/bean-component/
Bean과 Component 차이
스프링은 개발의 제어권이 스프링 컨테이너(IoC 컨테이너)에 있다고 한다. 그래서 이를 IoC(Inversion Of Control), 제어의 역전이라고 한다. 스프링이 개발자 대신 객체를 제어하기 위해서는 객체들이
youngjinmo.github.io
https://pamyferret.tistory.com/23
@Bean과 @Component 차이점
개발을 하다보니 @Component 어노테이션을 많이 사용하게 되었다. 특히 팩토리 패턴에서는 팩토리 역할을 하는 객체 및 팩토리 객체에서 생성되는 객체들을 @Component 어노테이션을 붙여 빈 생성을
pamyferret.tistory.com
[Spring] POJO란?
스프링의 본질은 엔터프라이즈 서비스 기능을 POJO에 제공하는 것이다 - Professional Spring Framework, 2005 🌱 POJO란? Plain Old Java Object, 단순한 자바 오브젝트 POJO란, 객체 지향적인 원리에 충실하면서..
doing7.tistory.com
'CS' 카테고리의 다른 글
Java에 대하여 - 3 (0) | 2022.06.10 |
---|---|
Java에 대하여 - 2 (0) | 2022.06.08 |
Java에 대하여 - 1 (0) | 2022.06.08 |
Spring에 대하여 - 2 (0) | 2022.06.03 |
Spring에 대하여 - 1 (0) | 2022.06.02 |