728x90

일단 프로젝트에 필터(Filter)와 인터셉터(Interceptor)를 한꺼번에 만들어보겠습니다.

들어가면서 …

둘 다 웹 어플리케이션에서 HTTP 요청/응답을 가로채고 처리하는 역할을 합니다. 하지만 이 둘은 동작 방식과 사용 목적이 약간씩 다릅니다. 아래 표는 필터와 인터셉터의 차이점을 간단히 비교한 것입니다.

일단 요약부터 해보겠습니다.

구분필터(Filter)인터셉터(Intercepter)
위치서블릿 컨테이너 앞단서블릿 컨테이너 내부
등록web.xml 파일 또는 @WebFilter 어노테이션@Configuration 클래스 또는 @Component 어노테이션
적용 대상URL 패턴컨트롤러 또는 뷰 렌더링
작업 시기요청/응답 처리 전후컨트롤러 실행 전후, 뷰 렌더링 전후
필요한 초기화 작업필요함불필요함
작업 수행 방식ServletRequest, ServletResponse, FilterChain 사용HttpServletRequest, HttpServletResponse, Object, ModelAndView 사용

언제 어디서 어떻게 쓰이는가? 알고 싶지 않음?

실제로 필터와 인터셉터는 주로 로깅, 인코딩 설정, 보안, 세션 처리 등과 같은 공통적인 작업을 처리하는 데에 사용됩니다. 다만, 필터는 모든 URL 패턴에 대해 적용되므로 세밀한 제어가 어렵지만, 인터셉터는 컨트롤러나 뷰 렌더링에 대해 적용되므로 세밀한 제어가 가능합니다. 필터와 인터셉터는 상황에 맞게 선택하여 사용하는 것이 좋습니다.

필터 예시 코드

@WebFilter(filterName = "MyFilter", urlPatterns = { "/*" })
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 요청 처리 전 필터 작업 수행
        String encoding = request.getCharacterEncoding();
        if (encoding == null) {
            request.setCharacterEncoding("UTF-8");
        }
        // 다음 필터 또는 서블릿 호출
        chain.doFilter(request, response);
        // 응답 처리 후 필터 작업 수행
        response.setCharacterEncoding("UTF-8");
    }
}

위 예시에서는 모든 URL 패턴에 대해 MyFilter라는 이름의 필터를 등록하고 있습니다. doFilter() 메소드는 요청 처리 전 필터 작업과 응답 처리 후 필터 작업 사이에서 chain.doFilter()를 호출하여 요청/응답 데이터를 처리합니다.

인터셉터 예시 코드

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 컨트롤러 실행 전 작업 수행
        String path = request.getRequestURI();
        if (path.contains("/admin/")) {
            // 로그인이 필요한 페이지로 접근할 경우 로그인 페이지로 이동
            response.sendRedirect("/login");
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        // 컨트롤러 실행 후 뷰 렌더링 전 작업 수행
        if (modelAndView != null) {
            modelAndView.addObject("user", request.getSession().getAttribute("user"));
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
            Exception ex) throws Exception {
        // 뷰 렌더링 후 작업 수행
    }
}

위 예시에서는 MyInterceptor라는 이름의 인터셉터를 등록하고 있습니다. preHandle() 메소드에서는 관리자 페이지에 접근하는 경우 로그인 페이지로 이동하는 작업을 수행하고, postHandle() 메소드에서는 컨트롤러에서 사용할 모델에 세션에서 가져온 사용자 정보를 추가하는 작업을 수행합니다.

요약하면…

요약하자면, 필터는 서블릿 컨테이너 앞단에서 실행되고, 웹 애플리케이션에서 발생하는 모든 요청과 응답에 대해 처리를 수행합니다. 반면 인터셉터는 서블릿 컨테이너 내부에서 실행되고, 주로 컨트롤러 처리 전후에 작업을 수행합니다.

필터와 인터셉터는 모두 요청/응답 처리에 대한 추가 작업을 수행할 수 있는데, 필터는 URL 패턴에 대해 적용되고, 인터셉터는 컨트롤러나 뷰 렌더링에 대해 적용됩니다. 또한 필터는 초기화 작업이 필요하지만, 인터셉터는 빈으로 등록하여 간단하게 사용할 수 있습니다.


내저장소 바로가기 luxury515

728x90
<insert id="insertKycInfo">

INSERT INTO `okcoin_broker`.`user_kyc_info`(
`user_id`,
`kyc_info`,
`type`,
`country_id`,
`level`,
`status`,
`fail_reason`,
`remark`,
`create_time`,
`update_time`,
`exp_date`
) VALUES
<foreach collection="userKycInfo" item="element" index="index" open="(" separator="),(" close=")">

#{element.user_id},
<choose>
<when test="element.kyc_info ==null">null,</when>

<when test="element.kyc_info ==''">null,</when>

<otherwise>#{element.kyc_info},</otherwise>
</choose>
#{element.type},
#{element.country_id},
#{element.level},
#{element.status},
#{element.fail_reason},
#{element.remark},
date_format(STR_TO_DATE(#{element.create_time}, '%Y-%m-%d %H:%i:%s'), '%Y-%m-%d %H:%i:%s'),
date_format(STR_TO_DATE(#{element.update_time}, '%Y-%m-%d %H:%i:%s'), '%Y-%m-%d %H:%i:%s'),
<choose>
<when test="element.exp_date ==null">null</when>

<when test="element.exp_date ==''">null</when>

<otherwise>date_format(STR_TO_DATE(#{element.exp_date}, '%Y-%m-%d %H:%i:%s'), '%Y-%m-%d %H:%i:%s')</otherwise>
</choose>
</foreach>
ON DUPLICATE KEY UPDATE
user_id = VALUES(user_id),
<choose>
<when test="element.kyc_info ==null">kyc_info = null,</when>

<when test="element.kyc_info ==''">kyc_info = null,</when>

<otherwise>kyc_info = VALUES(kyc_info),</otherwise>
</choose>
type = VALUES (type),
country_id = VALUES (country_id),
level = VALUES (level),
status = VALUES (status),
fail_reason = VALUES (fail_reason),
remark = VALUES (remark),
create_time = date_format(STR_TO_DATE(VALUES(create_time), '%Y-%m-%d %H:%i:%s'), '%Y-%m-%d %H:%i:%s'),
update_time = date_format(STR_TO_DATE(VALUES(update_time), '%Y-%m-%d %H:%i:%s'), '%Y-%m-%d %H:%i:%s'),
<choose>
<when test="element.exp_date ==null">exp_date = null</when>

<when test="element.exp_date ==''">exp_date = null</when>

<otherwise>exp_date = date_format(STR_TO_DATE(VALUES(exp_date), '%Y-%m-%d %H:%i:%s'), '%Y-%m-%d %H:%i:%s')</otherwise>
</choose>
</insert>


내저장소 바로가기 luxury515

728x90
  • 시스템 셋팅

AWS CLI 설치 : https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/install-macos.html

AWS 인증용 profile 셋팅 : profile 명 exkr-kms

$ aws configure --profile exkr-kms
AWS Access Key ID [None]: AKIAJHQMLLDJRWODVZBQ
AWS Secret Access Key [None]: 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
Default region name [None]: ap-northeast-2
  • KMSManager 사용법

aws/KMSManagerExample.java

  1. KMSManager 초기화
KMSManager kmsManager = KMSManager.getInstance(); 
kmsManager.init((String) System.getProperties().get("exkr.kms.alias"));

2. 사용자별(uid) cipher 생성

String cipher = kmsManager.createCipherWithUID(uid);

3. uid와 cipher로 암호화

String encrypted = kmsManager.encryptWithUID(uid, plain, cipher);

4. uid와 cipher로 복호화

String decrypted = kmsManager.decryptWithUID(uid, encrypted, cipher);

서비스 프로퍼티 암호화 : 실행 옵션 exkr.kms.cipher 사용하여 암/복호화

예제 소스들 ~~~~

예제 프로젝트

1. resources/META-INF/spring.factories  추가 
org.springframework.context.ApplicationContextInitializer=com.example.springapiexample.init.DecryptPropertiesContextInitializer

2. resources/application.properties 에 예제 프로퍼티 추가
exkr.test={cipher}743QDr/oHPyshILBgJURgXfqyUe4ZHgpKDx2qRwVR1k=

3. curl -si localhost:8080/greeting  호출시 exkr.test 복화화되어 출력 '안녕하세요!'포함한 문자열 
{"id":1,"content":"Hello, 안녕하세요?! with World pwd"}
~~~


내저장소 바로가기 luxury515

'Back-end > 기타' 카테고리의 다른 글

필터(Filter) vs 인터셉터(Intercepter)  (0) 2023.04.17
on duplicate key update  (0) 2023.04.16
DI(Depandency Injection) 에 관하여  (0) 2023.04.14
plantUml preview 갑자기 작동안될때.  (0) 2023.04.14
gradle bootrun 작동 에러  (0) 2023.04.14
728x90

현재 Spring에서 아래와 같이 3가지 DI 방식을 사용하고 있다.

  • 가장 흔한 필드 주입방식: Field Injection 방식 (비 권장)
    @Controller
    public class BoardController {
    	@Autowired 
      private IBoardItemService boardItemService;
    }
  • 수정자 주입: Setter Injection
    private IBoardItemService boardItemService;
      @Autowired // 4.3 부터 생략 가능
      public void SetIBoardItemService (MessageSource messageSource){
        this.messageSource = messageSource;
      }
  • 생성자 주입: 가장 선호하는 방식 ( Class 상단에 @RequiredArgsConstructor 추가 , @AllArgsConstructor 는 지운다!)
    @RequiredArgsConstructor
    public class BoardController {
    	private final IBoardItemService boardItemService;
    }

    Lombok 없이 사용시:

    
    public class BoardController {
    	private final IBoardItemService boardItemService; // Immutability 이슈까지 해결하고 싶다면 private final 접근자 붙여주기
        
    		@Autowired
    		public BoardController(IBoardItemService boardItemService) {
        	this.boardItemService = boardItemService;
        }
    } 

내저장소 바로가기 luxury515

'Back-end > 기타' 카테고리의 다른 글

on duplicate key update  (0) 2023.04.16
AWS KMS 관련 세팅  (0) 2023.04.14
plantUml preview 갑자기 작동안될때.  (0) 2023.04.14
gradle bootrun 작동 에러  (0) 2023.04.14
radius(레이디스)서버  (0) 2023.04.14

+ Recent posts