delpho

Spring에 대하여 - 3 본문

CS

Spring에 대하여 - 3

delpho 2022. 6. 4. 01:57

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 비교

 

 

 

# 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

 

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8F#CORS_(Cross-Origin_Resource_Sharing)_%3C%EA%B5%90%EC%B0%A8&%EB%8B%A4%EB%A5%B8_%EC%B6%9C%EC%B2%98_%EB%A6%AC%EC%86%8C%EC%8A%A4_%EA%B3%B5%EC%9C%A0%3E 

 

[WEB] 📚 CORS 개념 💯 완벽 정리 & 해결 방법 👏

CORS(Cross Origin Resource Sharing) CORS 정책은 우리가 가져오는 리소스들이 안전한지 검사하는 관문이다. 웹개발을 하는 사람들은 이 CORS 정책위반으로 인해 에러가 나는 상황을 많이들 겪어봤을것이라

inpa.tistory.com

https://wonit.tistory.com/572

 

[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

https://doing7.tistory.com/81

 

[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